/****************************************************
 * File: gtktrack.c
 *
 * Author: Fred Engler
 *
 * Description: Contains the implementation of the
 * GtkTrack widget.  This includes the Edit Track Properties
 * windows.  Routines for filling the track
 * with data from the root and markerlistroot structures
 * is also included here.  If you are unfamiliar with
 * how widgets are written, you may want to check out
 * Havoc Pennington's book "GTK+/Gnome Application
 * Development", especially chapters 3, 10, and 11.
 * ISBN #: 0-7357-0078-8
 ****************************************************/

#include "gtktrack.h"
#include "gtkfpcruler.h"
#include "gtkhighlight.h"
#include "../seq/tree.h"
#include "../seq/seq.h"

/*Make s all lowercase*/
#define STRLWR(s) {for(i=0;i<strlen(s);i++) s[i]=tolower(s[i]);}

extern float display_zoom;
extern int track_num;
extern int mergeoffset;
extern GtkWidget *ctg_window;
extern GtkWidget *merge_window2;
extern GtkWidget *merge_window1;
extern GtkWidget *tracks[];
extern void reorder_tracks();
extern void displaymarker();
extern void displaysequence(FPC_SEQ* pseq);
extern GtkObject *main_hadj;
extern void clone_edit_help();
extern void marker_edit_help();
extern void remark_edit_help();
extern void anchor_edit_help();
extern void addgel();
extern void gelredraw();
extern void copy_to_save_pixmap();
extern void refresh_track_colors();
extern void move_selected();
extern int intervals_overlap(int,int,int,int);

/*fred 2/26/04*/
extern int glbl_show_anchor_bins;
extern int glbl_show_anchor_pos;
extern int glbl_show_anchor_lines;

extern int seq_count_contig_hits(FPC_SEQ* pseq, int ctg);
extern void compute_seq_location(FPC_SEQ* seq,struct seqctgpos* ctgpos,int pagel, int pager, int *left, int *right) ;

extern float horiz_scale_factor;

extern int seqctg_hits_ctg(FPC_SEQ* pseq, int ctg);

/*Track widget initialization*/
static void   gtk_track_class_init    (GtkTrackClass  *klass);
static void   gtk_track_init          (GtkTrack       *track);

/* GtkObject functions */
static void   gtk_track_destroy       (GtkObject   *object);

extern GtkWidget *fpcruler;

/*GtkTrack-specific functions*/
static void free_filters(struct filters *p);
static int expose_event(GtkWidget *widget, GdkEventExpose *event, GtkTrack *track);
static void delete_track(GtkWidget *widget, GtkTrack *track);
static void fingerprint_callback(GtkWidget *widget, GtkTrack *track);
static void gel_callback(GtkWidget *widget, GtkTrack *track);
static void select_clone_callback(GtkWidget *widget, GtkTrack *track);
//static void seq_cycle_callback(GtkWidget *widget, GtkTrack *track);
static void toggle_anchor_bin_viewing(GtkWidget *widget, GtkTrack *track);
static void toggle_anchor_pos_viewing(GtkWidget *widget, GtkTrack *track);
static void toggle_anchor_line_viewing(GtkWidget *widget, GtkTrack *track);
static void destroy_edit_track_callback(GtkWidget *widget, GtkTrack *track);
//void entity_highlight(GtkTrack *t, int index, enum highlightTypes mode);
static void clone_edit_track(GtkTrack *track);
static void generic_edit_track(GtkWidget *widget, GtkTrack *track);
static void remove_filter(GtkWidget *widget, GtkTrack *track);
static void custom_color_callback(GtkWidget *widget, GtkTrack *track);
static gint gtk_track_button_press(GtkWidget *widget, GdkEventButton *event);
static gint gtk_track_button_release(GtkWidget *widget, GdkEventButton *event);
static gint gtk_track_motion(GtkWidget *widget, GdkEventMotion *event);
static void draw_entities(GtkTrack *track);
static void gtk_track_draw_contents(GtkTrack *t);
static void get_clone_filter_text(struct filters *fptr, gchar **text);
static void get_marker_filter_text(struct filters *fptr, gchar **text);
static void get_remark_filter_text(struct filters *fptr, gchar **text);
static void get_anchor_filter_text(struct filters *fptr, gchar **text);
static int bins_match(char *a, char *b);
static void detail_print_dialog();

void* lfind_fpc(const void* key, const void* base, int* nmemb, int size, int(*compar)(const void*, const void*));
void* lsearch_fpc(const void* key, const void* base, int* nmemb, int size, int(*compar)(const void*, const void*));

extern int intervals_overlap(int x,int y,int a,int b);
/**************************************************************************
 for the sequence track detail view print function */

#define MAX_PRINT_COMMAND_LEN 30

enum save_types {JPEG, GIF, TIFF, PNG, BITMAP};
static enum save_types save_type = JPEG;

static int action = 0;      /* 0 -> send to printer; 1 -> save to file*/
static char print_command[MAX_PRINT_COMMAND_LEN + 1] = "lpr";  /* The print command string*/
static char save_file[MAX_PRINT_COMMAND_LEN + 1];              /* The save command string*/

static GtkWidget *print_window=NULL;            /* The print dialog window*/
static GtkWidget *entry1;                /* The print command entry*/
static GtkWidget *entry2;                /* The save command entry*/
static GtkWidget *save_optionmenu;       /* File format option menu*/
static GtkWidget *action_button;         /* Either Save or Print*/
static GtkWidget *action_button_label;   /* String for action_button*/

/*******************************************************************************************/

void draw_sequence_hits(struct t_seq* pts, GtkTrack* t, int y_pix, int l_pix, int r_pix, int sleft, int sright, float corr);

int text_height = 0;
int HOTSPOT_HEIGHT = 18;
int assign_seq_rows(GtkTrack* t, int maxrow);

GtkWidget* detail_window = NULL;
GdkPixmap* detail_pm = NULL;
GdkGC* detail_gc;
GtkTrack* detail_track;
static int detail_flip_reversed;
GtkWidget *detail_drawing_area;

void get_string_dims(char* str,GtkWidget* t,int* pw, int* ph)
{

    int w;
    int h;
    PangoLayout *pl = gtk_widget_create_pango_layout(GTK_WIDGET(t),str);
    pango_layout_get_size(pl,&w,&h);
    if (pw)
    {
        *pw = (int)(w/PANGO_SCALE);
    }
    if (ph)
    {
        *ph = (int)(h/PANGO_SCALE);
    }
    g_object_unref(pl);
}


/* The GtkTrack is a child of the GtkVBox class*/
static GtkVBoxClass *parent_class = NULL;

/*                     DEF: gtk_track_get_type
 * Boilerplate widget initialization*/
GtkType
gtk_track_get_type (void)
{
  static GtkType track_type = 0;

  if (!track_type)
    {
      static const GtkTypeInfo track_info =
      {
        "GtkTrack",
        sizeof (GtkTrack),
        sizeof (GtkTrackClass),
        (GtkClassInitFunc) gtk_track_class_init,
        (GtkObjectInitFunc) gtk_track_init,
        /* reserved_1 */ NULL,
        /* reserved_2 */ NULL,
        (GtkClassInitFunc) NULL,
      };

      track_type = gtk_type_unique (GTK_TYPE_VBOX, &track_info);
    }

  return track_type;
}

static void
gtk_track_class_init (GtkTrackClass *klass)
{
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;

  object_class = (GtkObjectClass*) klass;
  widget_class = (GtkWidgetClass*) klass;
  container_class = (GtkContainerClass*) klass;

  parent_class = gtk_type_class (GTK_TYPE_VBOX);

  object_class->destroy = gtk_track_destroy;

  widget_class->button_press_event = gtk_track_button_press;
  widget_class->button_release_event = gtk_track_button_release;
  widget_class->motion_notify_event = gtk_track_motion;
}

/**************************************************
                 DEF: close_button_callback
cari 10.5.4
**************************************************/
static void
close_button_callback( GtkWidget *widget,
                           gpointer   data ){
  if(ctg_window!=NULL) gtk_widget_destroy(ctg_window);
  if (merge_window2!=NULL) gtk_widget_destroy(merge_window2);
  if (merge_window1!=NULL) gtk_widget_destroy(merge_window1);
}
void draw_string(GtkWidget* t, GdkDrawable* draw, GdkGC* gc, char* str, int x, int y)
{
     PangoLayout *pl = gtk_widget_create_pango_layout(GTK_WIDGET(t),str);
     gdk_draw_layout(draw,gc, x, y, pl);
     g_object_unref(pl);
}
static int detail_configure_event(GtkWidget *widget, GdkEventConfigure *event, GtkWidget* drawing_area)
{
    int height, width;
    GdkColor color;
    char str[100];
    struct t_seq* ts;
    int i, x, y, name_width, sy, cy, seq_loc, name_height,y1,y2,seq_start,seq_end;
    int col_width = 150;
    int bar_width = 15;
    int gap_bar_width = 5;
    int gap_diff = 5;
    int offset_top = 30;
    int start_left = 50;
    SEQHIT *hit;
    float bp2cb;
    struct seqctgpos *loc;  
    CLONE* clp; 
    struct fpc_seq_list * ctgs;
    int flip;

    col_width = (detail_track->numdata > 2 ? 150 : 250); 

    gdk_drawable_get_size(drawing_area->window,&width,&height);

    if (detail_gc != NULL)
    {
        gdk_gc_destroy(detail_gc);
        detail_gc = NULL;
    }
    detail_gc = gdk_gc_new(drawing_area->window);

    if (detail_pm != NULL)
    {
        gdk_pixmap_unref(detail_pm);
        detail_pm = NULL;
    }
    detail_pm = gdk_pixmap_new(drawing_area->window,width,height,-1);

    gdk_color_parse("white", &color);
    gdk_gc_set_rgb_fg_color(detail_gc,&color);
    gdk_draw_rectangle(detail_pm, detail_gc, TRUE,0,0,  width, height);

    gdk_color_parse("gray", &color);
    gdk_gc_set_rgb_fg_color(detail_gc,&color);
    height = contigs[currentctg].right - contigs[currentctg].left;

    gdk_draw_rectangle(detail_pm, detail_gc, TRUE,start_left,offset_top,  bar_width, height);


    for (i = 0; i <= height; i += 100)
    {
        y = offset_top + i;
        gdk_draw_line (detail_pm, detail_gc, start_left - 15,y,start_left , y);    
        sprintf(str,"%d",i);
        get_string_dims(str,GTK_WIDGET(detail_track),&name_width,&name_height); 
        draw_string(drawing_area, detail_pm, detail_gc, str,  start_left - name_width -2, y+2);

    }

    gdk_color_parse("black", &color);
    gdk_gc_set_rgb_fg_color(detail_gc,&color);
    sprintf(str,"Ctg%d",currentctg);
    get_string_dims(str,GTK_WIDGET(detail_track),&name_width,0); 
    draw_string(drawing_area, detail_pm, detail_gc, str,  start_left - name_width/2 + bar_width/2, 12);

    gdk_draw_drawable(drawing_area->window, detail_gc, detail_pm,0,0,0,0,width,height);


    for (i=0; i < detail_track->numdata; i++)
    {
        ts = &(detail_track->data.seqList[i]);
        x = start_left + (i+1)*col_width;
        y = offset_top + ts->left;
        height = ts->right - ts->left;

        gdk_color_parse("gray", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);

        loc = ts->ctgpos;
        bp2cb = ((float)ts->right - (float)ts->left)/((float)loc->seq_end - (float)loc->seq_start);
        flip = (detail_flip_reversed==1 && (loc->corr < 0)); 
     

        gdk_color_parse("black", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);

        get_string_dims(ts->seq->name,GTK_WIDGET(detail_track),&name_width,0); 
        draw_string(drawing_area, detail_pm, detail_gc, ts->seq->name, x - name_width/2 + bar_width/2,y-18 );  

        sprintf(str,"%d kb",loc->seq_start/1000);
        draw_string(drawing_area, detail_pm, detail_gc,str , x + bar_width + 2, y );  
        sprintf(str,"%d kb",loc->seq_end/1000);
        draw_string(drawing_area, detail_pm, detail_gc,str , x + bar_width + 2, y + height );  

        /* Draw all the hits for the seq and its seqctgs, if any */


        for (hit = ts->seq->hits; hit; hit = hit->next)
        {

            clp = arrp(acedata, hit->clone_idx,CLONE);

            if (clp->ctg != currentctg) continue;
            if (clp->x < loc->ctg_start || clp->y > loc->ctg_end) continue;

            seq_loc = (int)((hit->seq_start + hit->seq_end)/2);

            if (seq_loc < loc->seq_start || seq_loc > loc->seq_end) continue;

            sy = y + (int)(bp2cb*(seq_loc - loc->seq_start));
            if (flip)
            {
                sy = y + height - (int)(bp2cb*(seq_loc - loc->seq_start));
            }
            cy = offset_top + (clp->x + clp->y)/2;

            gdk_color_parse("blue", &color);
            gdk_gc_set_rgb_fg_color(detail_gc,&color);
            gdk_draw_line (detail_pm, detail_gc, x,sy,start_left + bar_width, cy);
        }
        
        /* now we have to replicate this loop exactly for the seqctgs !! Not pretty. */

        for (ctgs = ts->seq->ctgs; ctgs; ctgs = ctgs->next)
        {
            for (hit = ctgs->seq->hits; hit; hit = hit->next)
            {

                clp = arrp(acedata, hit->clone_idx,CLONE);

                if (clp->ctg != currentctg) continue;
                if (clp->x < loc->ctg_start || clp->y > loc->ctg_end) continue;

                /* don't forget to offset the seqctg hit location by its position in the supercontig */
                seq_loc = ctgs->seq->pos + (int)((hit->seq_start + hit->seq_end)/2);

                if (seq_loc < loc->seq_start || seq_loc > loc->seq_end) continue;

                sy = y + (int)(bp2cb*(seq_loc - loc->seq_start));
                if (flip)
                {
                    sy = y + height - (int)(bp2cb*(seq_loc - loc->seq_start));
                }
                cy = offset_top + (clp->x + clp->y)/2;

                gdk_color_parse("blue", &color);
                gdk_gc_set_rgb_fg_color(detail_gc,&color);
                gdk_draw_line (detail_pm, detail_gc, x,sy,start_left + bar_width, cy);
            }
    
        }
    }

    for (i=0; i < detail_track->numdata; i++)
    {
        ts = &(detail_track->data.seqList[i]);
        x = start_left + (i+1)*col_width;
        y = offset_top + ts->left;
        height = ts->right - ts->left;

        gdk_color_parse("gray", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);

        loc = ts->ctgpos;
        bp2cb = ((float)ts->right - (float)ts->left)/((float)loc->seq_end - (float)loc->seq_start);
        flip = (detail_flip_reversed==1 && (loc->corr < 0)); 

        if (!ts->seq->ctgs)
        {

            gdk_draw_rectangle(detail_pm, detail_gc, TRUE,x,y,bar_width, height);   
        }
        else
        {

            gdk_draw_rectangle(detail_pm, detail_gc, TRUE,x+gap_diff,y,gap_bar_width, height);   

            for (ctgs = ts->seq->ctgs; ctgs; ctgs = ctgs->next)
            {
                if (ctgs->seq->pos <= loc->seq_end && ctgs->seq->pos + ctgs->seq->length >= loc->seq_start)
                {
                    seq_start = MaX(loc->seq_start,ctgs->seq->pos);   
                    seq_end = MiN(loc->seq_end,ctgs->seq->pos + ctgs->seq->length);  

                    y1 = y + bp2cb*(seq_start - loc->seq_start); 
                    y2 = y + bp2cb*(seq_end - loc->seq_start); 

                    gdk_draw_rectangle(detail_pm, detail_gc, TRUE,x,y1,bar_width, y2-y1); 
                }
            }
        }

   

        get_string_dims(ts->seq->name,GTK_WIDGET(detail_track),&name_width,&name_height); 
        gdk_color_parse("white", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        gdk_draw_rectangle(detail_pm, detail_gc, TRUE, x - name_width/2 + bar_width/2 - 1,y-19,name_width+2, name_height+2);  

        gdk_color_parse("black", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        draw_string(drawing_area, detail_pm, detail_gc, ts->seq->name, x - name_width/2 + bar_width/2,y-18 );  

        loc = ts->ctgpos;
        sprintf(str,"%d kb",(flip ? loc->seq_end/1000 : loc->seq_start/1000));
        get_string_dims(str,GTK_WIDGET(detail_track),&name_width,&name_height);
        gdk_color_parse("white", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        gdk_draw_rectangle(detail_pm, detail_gc, TRUE, x + bar_width + 1,y - 1, name_width+2, name_height+2);   
        gdk_color_parse("black", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        draw_string(drawing_area, detail_pm, detail_gc,str , x + bar_width + 2, y );  
        

        sprintf(str,"%d kb",(flip ? loc->seq_start/1000 : loc->seq_end/1000));
        get_string_dims(str,GTK_WIDGET(detail_track),&name_width,&name_height);
        gdk_color_parse("white", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        gdk_draw_rectangle(detail_pm, detail_gc, TRUE, x + bar_width + 1,y + height - 1, name_width+2, name_height+2);   
        gdk_color_parse("black", &color);
        gdk_gc_set_rgb_fg_color(detail_gc,&color);
        draw_string(drawing_area, detail_pm, detail_gc,str , x + bar_width + 2, y + height );  


    }

    return TRUE;
}


static int detail_expose_event(GtkWidget *widget, GdkEventExpose *event, GtkWidget *drawing_area)
{
    int height, width;
    GdkColor color;

    gdk_color_parse("white", &color);
    gdk_gc_set_rgb_fg_color(detail_gc,&color);

    gdk_drawable_get_size(drawing_area->window,&width,&height);

    //gdk_draw_rectangle(drawing_area->window, detail_gc, TRUE,0,0,  width, height);

    gdk_draw_drawable(drawing_area->window, detail_gc, detail_pm,0,0,0,0,width,height);


    return TRUE;
}

static void
detail_quit_button_callback( GtkWidget *widget,
                           gpointer   data )
{
  if(detail_window!=NULL) gtk_widget_destroy(GTK_WIDGET(detail_window));

}
static void
detail_flip_reversed_toggle( GtkWidget *widget,
                           gpointer   data )
{
    int width, height;
    GdkColor color;

    detail_flip_reversed = (detail_flip_reversed ? 0 : 1);

    gdk_color_parse("white", &color);
    gdk_gc_set_rgb_fg_color(detail_gc,&color);
    gdk_drawable_get_size(detail_drawing_area->window,&width,&height);
    gdk_draw_rectangle(detail_drawing_area->window, detail_gc, TRUE,0,0,  width, height);

    detail_configure_event(0,0, detail_drawing_area);
    detail_expose_event(0, 0, detail_drawing_area);
}

static GtkItemFactory *detail_item_factory;




static GtkItemFactoryEntry detail_menu_items[] = {
  { "/File", NULL, NULL, 0, "<Branch>" },
  { "/File/Close", "<control>Q", detail_quit_button_callback, 0, NULL },
  { "/File/Save or Print", NULL, detail_print_dialog, 0, NULL },

  { "/Analysis", NULL, NULL, 0, "<Branch>" },
  { "/Analysis/Flip Reversed", NULL, detail_flip_reversed_toggle, 0, NULL }
};
/*                    DEF: get_main_menu
 *Create menubar with the menu_items*/
static void
detail_main_menu( GtkWidget  *window,
               GtkWidget **menubar )
{
  GtkAccelGroup *accel_group;
  gint nmenu_items = sizeof (detail_menu_items) / sizeof (detail_menu_items[0]);

  accel_group = gtk_accel_group_new ();

  detail_item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
                                       accel_group);

  gtk_item_factory_create_items (detail_item_factory, nmenu_items, detail_menu_items, NULL);

  gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);

  if (menubar)
    /* Finally, return the actual menu bar created by the item factory. */
    *menubar = gtk_item_factory_get_widget (detail_item_factory, "<main>");
}
static void detailed_alignment( GtkWidget *widget, gpointer   data )
{
    GtkWidget *vbox;
    GtkWidget *hbox;
    int width,height;
    GtkWidget* scrolled_window;
    int col_width = 150;
    int start_left = 50;
    GtkWidget *menubar;
 
    detail_flip_reversed = 0;   
    detail_track = (GtkTrack*)data;

    col_width = (detail_track->numdata > 2 ? 150 : 250); 

    height = MiN(gdk_screen_height()/1.2,contigs[currentctg].right - contigs[currentctg].left + 50);
    width = 500;

    if (detail_window != NULL)
    {
        gtk_widget_destroy(detail_window);
        detail_window = NULL;
    }
    detail_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_default_size(GTK_WINDOW (detail_window),width,height);

    gtk_window_set_title (GTK_WINDOW (detail_window), "detail view");
    gtk_window_set_resizable (GTK_WINDOW (detail_window),TRUE);

    vbox=gtk_vbox_new(FALSE, 5);
    gtk_container_add (GTK_CONTAINER (detail_window), vbox);

    hbox=gtk_hbox_new(FALSE,1);
    detail_main_menu (detail_window, &menubar);
    gtk_box_pack_start (GTK_BOX (hbox), menubar, TRUE, TRUE, 0);
    gtk_widget_show (menubar);
    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

    scrolled_window=gtk_scrolled_window_new(NULL,NULL);
    gtk_widget_set_size_request(scrolled_window, width,height);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrolled_window), GTK_CORNER_TOP_LEFT);
    gtk_widget_show(scrolled_window);
    gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, FALSE, FALSE, 0);

    //gtk_container_add (GTK_CONTAINER (detail_window), scrolled_window);

    detail_drawing_area=gtk_drawing_area_new();
    height = contigs[currentctg].right - contigs[currentctg].left + 50;
    width = MaX(500,col_width*(1 + detail_track->numdata) + start_left);
    gtk_widget_set_size_request(GTK_WIDGET(detail_drawing_area),width,height);
    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),detail_drawing_area);
    gtk_signal_connect (GTK_OBJECT(detail_drawing_area),"configure_event",
		        (GtkSignalFunc) detail_configure_event, detail_drawing_area);
    gtk_signal_connect (GTK_OBJECT (detail_drawing_area), "expose_event",
		        (GtkSignalFunc) detail_expose_event, detail_drawing_area);


    gtk_widget_show_all (detail_window);

}


/*                     DEF: gtk_track_init
 * Create the composite widget, composed of a scrolled window
 * containing a drawing_area, as well as a second drawing area
 * for resizing the track. Also sets defaults for
 * the track variables*/
static void
gtk_track_init (GtkTrack *track)
{
  GtkWidget *edit_item;
  GtkWidget *delete_item;
  GtkWidget *quit_item;
  int track_height_px;

  track->numrows=20;
  track->rowspacing=15; /* Gets changed in gtk_track_set_entity... this is just default for empty track*/
  track->default_height=200;
  track->contig_pixel_width=(page_end_right - page_end_left + 1) *
                            display_zoom * horiz_scale_factor;
  track->contig_pixel_height=track->numrows * track->rowspacing;

  /* The scrolled window is the shell of the track*/
  track_height_px = MIN(track->default_height - RESIZE_AREA_HEIGHT,
                           track->contig_pixel_height);

  track->scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_widget_set_size_request(track->scrolled_window,
                    DEFAULT_TRACK_WIDTH   , track_height_px
                       );
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(track->scrolled_window),
                                 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
  gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(track->scrolled_window),
                                    GTK_CORNER_TOP_RIGHT);
  gtk_box_pack_start(GTK_BOX(track),track->scrolled_window,TRUE,TRUE,0);
  gtk_widget_show(track->scrolled_window);

  /* Let us draw in the window*/
  track->drawing_area=gtk_drawing_area_new();
  gtk_widget_set_size_request(GTK_WIDGET(track->drawing_area),
                        (track->entity == ANCHORS ? DEFAULT_TRACK_WIDTH :track->contig_pixel_width),
                        track->contig_pixel_height);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(track->scrolled_window),
                                         track->drawing_area);
  gtk_signal_connect (GTK_OBJECT(track->drawing_area),"configure_event",
		      (GtkSignalFunc) configure_event, track);
  gtk_signal_connect (GTK_OBJECT (track->drawing_area), "expose_event",
		      (GtkSignalFunc) expose_event, track);

  gtk_widget_set_events (track->drawing_area, GDK_EXPOSURE_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_KEY_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK);
  gtk_widget_show(track->drawing_area);

  /* Make track user-resizable*/
  track->resize_area=gtk_drawing_area_new();
  gtk_widget_set_size_request(GTK_WIDGET(track->resize_area),
                        0,
                        RESIZE_AREA_HEIGHT);
  gtk_box_pack_start(GTK_BOX(track),track->resize_area,FALSE,FALSE,0);
  gtk_signal_connect (GTK_OBJECT(track->resize_area),"expose_event",
		      (GtkSignalFunc) expose_event, track);
  gtk_widget_set_events (track->resize_area, GDK_EXPOSURE_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK);
  gtk_widget_show(track->resize_area);

  /* Draw everything to a pixmap and then expose as needed (allocated in configure_event)*/
  track->pixmap=NULL;

  /* Defaults*/
  track->shade_pixmap=NULL;
  track->mask=NULL;
  track->entity=NONE;
  track->filterList=NULL;
  track->colormap=gdk_colormap_get_system();
  track->selected_filter=-1;
  track->in_drag=FALSE;
  track->view_height=0;
  track->gc=NULL;
  track->xor_gc=NULL;
  track->high_gc=NULL;
  track->shade_gc=NULL;
  track->cursor_set=FALSE;
  track->highdata=-1;
  track->hadj=NULL;
  track->track_pos=track_num+1;
  track->track_pos_new=track_num+1;
  track->limit_rows=FALSE;
  track->row_policy=AUTO_POLICY;
  track->edit_track_window=NULL;
  track->show_anchor_bins=FALSE;
  track->show_anchor_pos=FALSE;
  track->show_anchor_lines=TRUE;

  /* Create generic popup menu*/
  track->generic_popup_menu=gtk_menu_new();
  quit_item=gtk_menu_item_new_with_label("Close contig");
  gtk_menu_append(GTK_MENU(track->generic_popup_menu),quit_item);
  gtk_signal_connect_object(GTK_OBJECT(quit_item),"activate",
                     /* cari 10.5.4 GTK_SIGNAL_FUNC(gtk_widget_destroy),*/
                     GTK_SIGNAL_FUNC(close_button_callback),
                     GTK_OBJECT(ctg_window));
  gtk_widget_show(quit_item);

  edit_item=gtk_menu_item_new_with_label("Edit track properties");
  gtk_menu_append(GTK_MENU(track->generic_popup_menu),edit_item);
  gtk_signal_connect(GTK_OBJECT(edit_item),"activate",
                     GTK_SIGNAL_FUNC(generic_edit_track),track);
  gtk_widget_show(edit_item);

  delete_item=gtk_menu_item_new_with_label("Remove track");
  gtk_menu_append(GTK_MENU(track->generic_popup_menu),delete_item);
  gtk_signal_connect(GTK_OBJECT(delete_item),"activate",
                     GTK_SIGNAL_FUNC(delete_track),track);
  gtk_widget_show(delete_item);


  /* Create popup menu object right-clicks*/
  track->clone_popup_menu=gtk_menu_new();


}

GtkWidget*
gtk_track_new ()
{
  GtkTrack *track;

  track = gtk_type_new (gtk_track_get_type ());
  return GTK_WIDGET (track);
}

/*                     DEF: gtk_track_set_hadjustment
 * Set the adjustment controlling the horizontal scrolling of the
 * scrolled window containing the main drawing area.  This makes
 * all tracks scroll with one scrollbar.*/
void
gtk_track_set_hadjustment(GtkTrack *track, GtkAdjustment *adj){
  g_return_if_fail(track != NULL);
  g_return_if_fail(GTK_IS_TRACK(track));
  if(adj!=NULL){
    g_return_if_fail(GTK_IS_ADJUSTMENT(adj));
    track->hadj = GTK_OBJECT(adj);
  }
  gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(track->scrolled_window),adj);
}

/*                     DEF: gtk_track_set_entity
 * Set the type of entities to be displayed in the track.  The last 3
 * parameters are only used for anchor tracks.*/
void
gtk_track_set_entity(GtkTrack *track, enum entities e,
                     int height, enum rowPolicies row_policy, int numrows,
                     int show_anchor_bins, int show_anchor_pos, int show_anchor_lines){
  char str[50];
  GtkWidget *showbin_item;
  GtkWidget *showbin_label;
  GtkWidget *showpos_item;
  GtkWidget *showpos_label;
  GtkWidget *draw_line_item;
  GtkWidget *draw_line_label;
  GtkWidget *fp_item;
  GtkWidget *gel_item;
  GtkWidget *select_item;
  GtkWidget *cycle_item;
  GtkWidget *detail_item;

  g_return_if_fail(track != NULL);
  g_return_if_fail(GTK_IS_TRACK(track));

  track->entity=e;
  track->default_height = height;
  track->row_policy=row_policy;
  track->numrows=numrows;
  track->show_anchor_bins=show_anchor_bins;
  track->show_anchor_pos=show_anchor_pos;
  track->show_anchor_lines=show_anchor_lines;
  switch(e){
    case CLONES:
      track->rowspacing=20;
      break;
    case MARKERS:
      track->rowspacing=15;
      break;
    case REMARKS:
      track->rowspacing=15;
      break;
    case ANCHORS:
      track->rowspacing=15;
      if(track->show_anchor_lines)
	sprintf(str, "Hide anchor lines");
      else
	sprintf(str, "Show anchor lines");

      draw_line_label = gtk_label_new(str);
      gtk_misc_set_alignment (GTK_MISC (draw_line_label), 0, 0.5);
      gtk_widget_show(draw_line_label);

      draw_line_item=gtk_menu_item_new();
      gtk_container_add(GTK_CONTAINER(draw_line_item), draw_line_label);
      gtk_signal_connect(GTK_OBJECT(draw_line_item),"activate",
			 GTK_SIGNAL_FUNC(toggle_anchor_line_viewing),
			 GTK_OBJECT(track));
      gtk_container_add (GTK_CONTAINER (track->generic_popup_menu), draw_line_item);
      gtk_widget_show(draw_line_item);

      if(Proj.anchor_label[0]!='\0'){
        if(track->show_anchor_bins)
          sprintf(str, "Hide anchor %s", Proj.anchor_label);
        else
          sprintf(str, "Show anchor %s", Proj.anchor_label);

        showbin_label = gtk_label_new(str);
        gtk_misc_set_alignment (GTK_MISC (showbin_label), 0, 0.5);
        gtk_widget_show(showbin_label);

	showbin_item=gtk_menu_item_new();
        gtk_container_add(GTK_CONTAINER(showbin_item), showbin_label);
	gtk_signal_connect(GTK_OBJECT(showbin_item),"activate",
			   GTK_SIGNAL_FUNC(toggle_anchor_bin_viewing),
			   GTK_OBJECT(track));
        gtk_container_add (GTK_CONTAINER (track->generic_popup_menu), showbin_item);
	gtk_widget_show(showbin_item);

        if(track->show_anchor_pos)
          sprintf(str, "Hide anchor positions");
        else
          sprintf(str, "Show anchor positions");

        showpos_label = gtk_label_new(str);
        gtk_misc_set_alignment (GTK_MISC (showpos_label), 0, 0.5);
        gtk_widget_show(showpos_label);

	showpos_item=gtk_menu_item_new();
        gtk_container_add(GTK_CONTAINER(showpos_item), showpos_label);
	gtk_signal_connect(GTK_OBJECT(showpos_item),"activate",
			   GTK_SIGNAL_FUNC(toggle_anchor_pos_viewing),
			   GTK_OBJECT(track));
        gtk_container_add (GTK_CONTAINER (track->generic_popup_menu), showpos_item);
	gtk_widget_show(showpos_item);
      }
      break;
    case SEQUENCE:
      track->rowspacing=50;
      break;
    case NONE:
      break;

  }

  if (e == CLONES) {
     fp_item=gtk_menu_item_new_with_label("Fingerprint");
     gtk_menu_append(GTK_MENU(track->clone_popup_menu),fp_item);
     gtk_signal_connect(GTK_OBJECT(fp_item),"activate",
                        GTK_SIGNAL_FUNC(fingerprint_callback),track);
     gtk_widget_show(fp_item);

     gel_item=gtk_menu_item_new_with_label("Gel Image");
     gtk_menu_append(GTK_MENU(track->clone_popup_menu),gel_item);
     gtk_signal_connect(GTK_OBJECT(gel_item),"activate",
                        GTK_SIGNAL_FUNC(gel_callback),track);
     gtk_widget_show(gel_item);

     select_item=gtk_menu_item_new_with_label("Select");
     gtk_menu_append(GTK_MENU(track->clone_popup_menu),select_item);
     gtk_signal_connect(GTK_OBJECT(select_item),"activate",
                        GTK_SIGNAL_FUNC(select_clone_callback),track);
     gtk_widget_show(select_item);
  }
  else if (e == SEQUENCE) {


    detail_item=gtk_menu_item_new_with_label("Show detailed alignment");
    gtk_menu_append(GTK_MENU(track->generic_popup_menu),detail_item);
    gtk_signal_connect(GTK_OBJECT(detail_item),"activate",
                     GTK_SIGNAL_FUNC(detailed_alignment),track);
    gtk_widget_show(detail_item);

     cycle_item=gtk_menu_item_new_with_label("Cycle On/Off");
     //gtk_menu_append(GTK_MENU(track->clone_popup_menu),cycle_item);
     //gtk_signal_connect(GTK_OBJECT(cycle_item),"activate",
      //                  GTK_SIGNAL_FUNC(seq_cycle_callback),track);
     //gtk_widget_show(cycle_item);
  }
}

/*                     DEF: gtk_track_add_dummy_filter
 * This is for the 'Click here to add filter' row
 * at the end of the filter list*/
static void
gtk_track_add_dummy_filter(GtkTrack *t){
  struct filters *fptr;

  g_return_if_fail(t != NULL);
  g_return_if_fail(GTK_IS_TRACK(t));

  if(t->filterList==NULL){
    fptr = t->filterList = (struct filters *) malloc(sizeof(struct filters));
  }
  else{
    for(fptr=t->filterList; fptr->next!=NULL; fptr=fptr->next)
      ;
    fptr->next = (struct filters *) malloc(sizeof(struct filters));  /*Create new extra one*/
    fptr=fptr->next;
  }
  strcpy(fptr->name, "");
  strcpy(fptr->remark, "");
  switch(t->entity){
    case CLONES:
      fptr->type=ANY_CLONE;
      break;
    case MARKERS:
      fptr->type=ANY_MARK;
      break;
    case REMARKS:
      fptr->type=ANY_REMARK;
      break;
    case ANCHORS:
      fptr->type=ANY_ANCHOR;
      break;
    case SEQUENCE:
      fptr->type=ANY_SEQ;
      break;
    case NONE:
      break;
  }
  fptr->status=ANY_STATUS;
  fptr->chrom=ANY_CHROM;
  fptr->attachment=ANY_ATTACH;
  fptr->color_choice=BLACK_COLOR;
  fptr->ignore=TRUE;
  fptr->next=NULL;
}

/*                     DEF: gtk_track_add_filter
 * Add a filter to the filter list*/
void
gtk_track_add_filter(GtkTrack *t, char *name, char *remark, int type,
                     int status, int chrom, int attach, enum colors color_choice,
                     GdkColor *clr){
  struct filters *fptr;

  g_return_if_fail(t != NULL);
  g_return_if_fail(GTK_IS_TRACK(t));

  if(t->filterList==NULL){
    fptr = t->filterList = (struct filters *) malloc(sizeof(struct filters));
    fptr->next=NULL;
    gtk_track_add_dummy_filter(t);
  }
  else{
    for(fptr=t->filterList; fptr->next!=NULL; fptr=fptr->next)
      ;
    gtk_track_add_dummy_filter(t);
  }

  strcpy(fptr->name, name);
  strcpy(fptr->remark, remark);
  fptr->type=type;
  fptr->status=status;
  fptr->chrom=chrom;
  fptr->attachment=attach;
  fptr->color_choice=color_choice;
  fptr->ignore=FALSE;

  switch(color_choice){
    case HIDE_COLOR:
      break;
    case BLACK_COLOR:
      if(gdk_color_parse("black", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case RED_COLOR:
      if(gdk_color_parse("red", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case ORANGE_COLOR:
      if(gdk_color_parse("orange", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case YELLOW_COLOR:
      if(gdk_color_parse("yellow", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case GREEN_COLOR:
      if(gdk_color_parse("green", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case BLUE_COLOR:
      if(gdk_color_parse("blue", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case VIOLET_COLOR:
      if(gdk_color_parse("violet", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case GRAY_COLOR:
      if(gdk_color_parse("gray", &(fptr->color))){
	if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
          g_warning("Could not allocate color");
	}
      }
      else{
        g_warning("Could not allocate color");
      }
      break;
    case CUSTOM_COLOR:
      g_return_if_fail(clr!=NULL);
      fptr->color = *clr;
      if(!gdk_colormap_alloc_color(t->colormap, &(fptr->color), FALSE, TRUE)){
        g_warning("Could not allocate color");
      }
      break;
  }
}

/*                     DEF: add_to_filterList
 * Called when the currently selected filter is the dummy filter and
 * one of the Selected filter edit widgets is changed, thus requiring
 * the creation of a new filter.*/
static void
add_to_filterList(GtkTrack *track){
  gchar *text[5];
  int i;

  for(i=0;i<5;i++) text[i] = (gchar *) malloc(sizeof(char[50]));
  switch(track->entity){
    case CLONES:
      gtk_track_add_filter(track, "", "", ANY_CLONE, ANY_STATUS, ANY_CHROM, ANY_ATTACH, BLACK_COLOR, NULL);
      strcpy(text[0],"[Select to add filter]");
      strcpy(text[1],"");
      strcpy(text[2],"");
      strcpy(text[3],"");
      strcpy(text[4],"");
      gtk_clist_append(GTK_CLIST(track->filter_clist), text);

      /* Set Name, Remark, Type, Status, and Color defaults*/
      get_clone_filter_text(track->current_filter,text);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,text[0]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,text[1]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,text[2]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,text[3]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,text[4]);
      break;
    case MARKERS:
      gtk_track_add_filter(track, "", "", ANY_MARK, ANY_STATUS, ANY_CHROM, ANY_ATTACH, BLACK_COLOR, NULL);
      strcpy(text[0],"[Select to add filter]");
      strcpy(text[1],"");
      strcpy(text[2],"");
      strcpy(text[3],"");
      strcpy(text[4],"");
      gtk_clist_append(GTK_CLIST(track->filter_clist), text);

      /* Set Name, Remark, Type, and Color defaults*/
      get_marker_filter_text(track->current_filter,text);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,text[0]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,text[1]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,text[2]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,text[3]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,text[4]);
      break;
    case REMARKS:
      gtk_track_add_filter(track, "", "", ANY_REMARK, ANY_STATUS, ANY_CHROM, ANY_ATTACH, BLACK_COLOR, NULL);
      strcpy(text[0],"[Select to add filter]");
      strcpy(text[1],"");
      strcpy(text[2],"");
      gtk_clist_append(GTK_CLIST(track->filter_clist), text);

      /* Set Name, Type, and Color defaults*/
      get_remark_filter_text(track->current_filter,text);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,text[0]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,text[1]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,text[2]);
      break;
    case ANCHORS:
      gtk_track_add_filter(track, "", "", ANY_ANCHOR, ANY_STATUS, ANY_CHROM, ANY_ATTACH, BLACK_COLOR, NULL);
      strcpy(text[0],"[Select to add filter]");
      strcpy(text[1],"");
      strcpy(text[2],"");
      strcpy(text[3],"");
      gtk_clist_append(GTK_CLIST(track->filter_clist), text);

      /* Set Name, Assign, Type, and Color defaults*/
      get_anchor_filter_text(track->current_filter,text);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,text[0]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,text[1]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,text[2]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,text[3]);
      break;
    case SEQUENCE:
      break;
      gtk_track_add_filter(track, "", "", ANY_SEQ, ANY_STATUS, ANY_CHROM, ANY_ATTACH, BLACK_COLOR, NULL);
      strcpy(text[0],"[Select to add filter]");
      strcpy(text[1],"");
      strcpy(text[2],"");
      strcpy(text[3],"");
      strcpy(text[4],"");
      gtk_clist_append(GTK_CLIST(track->filter_clist), text);

      /* Set Name, Remark, Type, and Color defaults*/
      get_marker_filter_text(track->current_filter,text);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,text[0]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,text[1]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,text[2]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,text[3]);
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,text[4]);
    case NONE:
      break;
  }
  for(i=0;i<5;i++) g_free(text[i]);
}

/*                     DEF: gtk_track_destroy
 * Called when a destroy signal is received by the track widget
 * Cleans up and frees memory held by the track.*/
static void
gtk_track_destroy       (GtkObject   *object)
{
  GtkTrack* track;
  int i;

  g_return_if_fail(object != NULL);
  g_return_if_fail(GTK_IS_TRACK(object));
  track = GTK_TRACK(object);

  // WMN this is because this routine gets called twice...I don't know why.
  if (track->pixmap == 0) return;  

  if(track->edit_track_window != NULL){
    gtk_widget_destroy(track->edit_track_window);
    track->edit_track_window=NULL;
  }

  free_filters(track->filterList);

  switch(track->entity){
    case MARKERS:
      for(i=0; i<track->numdata; i++){
        if(track->data.markerList[i].pixmap)
          gdk_pixmap_unref(track->data.markerList[i].pixmap);
			track->data.markerList[i].pixmap = 0;
      }
      g_free(track->data.markerList);
      break;
    case CLONES:
      for(i=0; i<track->numdata; i++){
        if(track->data.cloneList[i].pixmap)
          gdk_pixmap_unref(track->data.cloneList[i].pixmap);
			track->data.cloneList[i].pixmap = 0;
      }
      g_free(track->data.cloneList);
      break;
    case REMARKS:
      for(i=0; i<track->numdata; i++){
        if(track->data.remarkList[i].pixmap)
          gdk_pixmap_unref(track->data.remarkList[i].pixmap);
			track->data.remarkList[i].pixmap = 0;
      }
      g_free(track->data.remarkList);
      break;
    case ANCHORS:
      g_free(track->data.anchorList);
      break;
    case SEQUENCE:      
      for(i=0; i<track->numdata; i++){
        if(track->data.seqList[i].pixmap)
          gdk_pixmap_unref(track->data.seqList[i].pixmap);
			track->data.seqList[i].pixmap = 0;
      }
      g_free(track->data.seqList);
      break;
    case NONE:
      break;
  }
  if(track->gc) gdk_gc_unref(track->gc);
  if(track->xor_gc) gdk_gc_unref(track->xor_gc);
  if(track->high_gc) gdk_gc_unref(track->high_gc);
  if(track->shade_gc) gdk_gc_unref(track->shade_gc);
  if(track->dotln_gc) gdk_gc_unref(track->dotln_gc);

  if(track->pixmap) gdk_pixmap_unref(track->pixmap);

  track->pixmap = 0;
}

/*                     DEF: check_if_width_exceeded
 * See if the drawing area width is greater than GTK can display*/
static void
check_if_width_exceeded(GtkTrack *t){
  if(checked_width) return;
  if(t->contig_pixel_width>MAXIMUM_DISPLAY_WIDTH){
    messout("Maximum display width exceeded.  Cannot show tracks.  Reduce area displayed or zoom to view tracks.");
    checked_width=TRUE;
  }
}

/* GtkTrack-specific functions */

/*                     DEF: configure_event
 * Called once the drawing area is realized.  That is, we have attached this
 * function to the 'configure_event' signal of the track's drawing area.
 * Creates the pixmap to which the lines and text is drawn.*/
int
configure_event(GtkWidget *widget, GdkEventConfigure *event, GtkTrack *track){
  int width;

  if(track->pixmap){
    gdk_pixmap_unref(track->pixmap);
	track->pixmap = 0;
  }

  if(track->entity==ANCHORS){
    width=MIN((page_end_right - page_end_left + 1) * display_zoom * horiz_scale_factor,
	      MAX(track->scrolled_window->allocation.width-SCROLLBAR_WIDTH, 1));
    track->pixmap=gdk_pixmap_new(widget->window,
                                 width,
				 track->contig_pixel_height,
				 -1);
    if(track->shade_pixmap) gdk_pixmap_unref(track->shade_pixmap);
    track->shade_pixmap=gdk_pixmap_new(widget->window,
                                       width,
				       track->contig_pixel_height,
				       -1);
    if(track->mask) gdk_bitmap_unref(track->mask);
    track->mask=gdk_pixmap_new(widget->window,
                               width,
			       track->contig_pixel_height,
			       1);
  }
  else{
    track->pixmap=gdk_pixmap_new(widget->window,
				 track->contig_pixel_width,
				 track->contig_pixel_height,
				 -1);
  }
  check_if_width_exceeded(track);
  draw_entities(track);
  return TRUE;
}

/*                     DEF: expose_event
 * Called by GTK when a part of the pixmap gets exposed, either by
 * scrolling or by popping to the front after being hidden behind
 * another window.  Redraws the area of the pixmap that just got
 * uncovered*/
static int
expose_event(GtkWidget *widget, GdkEventExpose *event, GtkTrack *track){
  GdkCursor *cursor;
  GdkRectangle area;
   GdkEventExpose e;
    GtkWidget* w;

  if(widget==track->drawing_area){
     if(track->entity==ANCHORS){
       gdk_draw_pixmap(widget->window,
		       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
		       track->pixmap,
		       event->area.x, event->area.y,
		       event->area.x, event->area.y,
		       event->area.width, event->area.height);
     }
     else
       gdk_draw_pixmap(widget->window,
		       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
		       track->pixmap,
		       event->area.x, event->area.y,
		       event->area.x, event->area.y,
		       event->area.width, event->area.height);
  }
  else if(widget==track->resize_area){
    if(!track->cursor_set){
      track->cursor_set=TRUE;
      cursor=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW);
      gdk_window_set_cursor(widget->window,cursor);
      gdk_cursor_destroy(cursor);
    }

    area.x = 0;
    area.y = 0;
    area.width = widget->allocation.width;
    area.height = widget->allocation.height;

    gtk_paint_hline(widget->style, widget->window, GTK_STATE_NORMAL,
		    &area, widget, "track",
		    0, widget->allocation.width - 1,
		    widget->allocation.height/2-1);
  }
     e.area.x = event->area.x + widget->allocation.x ;
     e.area.y = event->area.y + widget->allocation.y;
    w = widget;
    while ( (w = gtk_widget_get_parent(w)) )
    {
        e.area.x += w->allocation.x ;
        e.area.y += w->allocation.y ;
    }
    e.area.width = event->area.width;
    e.area.height = event->area.height;


  return FALSE;
}

/*                     DEF: draw_entites
 * Set up the rectangle to draw, call the function to draw to the
 * pixmap, and queue the rectangle to be drawn*/
static void
draw_entities(GtkTrack *track){
   GdkRectangle update_rect;

   update_rect.x=0;
   update_rect.y=0;
   update_rect.width=track->drawing_area->allocation.width;
   update_rect.height=track->drawing_area->allocation.height;
   gdk_draw_rectangle(track->pixmap, track->drawing_area->style->white_gc,
		      TRUE,0,0,
		      track->drawing_area->allocation.width,
		      track->drawing_area->allocation.height);
   if(track->entity != NONE){
     gtk_track_draw_contents(track);
   }
   gtk_widget_draw(track->drawing_area,&update_rect);

//    draw_region_lines();
}

/*                     DEF: delete_track
 * Destroy the track if the user agrees after querying*/
static void
delete_track(GtkWidget *widget, GtkTrack *track){
  char mess_str[50];

  switch(track->entity){
    case MARKERS:
      sprintf(mess_str,"Remove marker track #%d?",track->track_pos);
      break;
    case CLONES:
      sprintf(mess_str,"Remove clone track #%d?",track->track_pos);
      break;
    case REMARKS:
      sprintf(mess_str,"Remove remark track #%d?",track->track_pos);
      break;
    case ANCHORS:
      sprintf(mess_str,"Remove anchor track #%d?",track->track_pos);
      break;
    case SEQUENCE:
    case NONE:
      sprintf(mess_str,"Remove track #%d?",track->track_pos);
      break;
  }
  if(messQuery(mess_str))
    gtk_widget_destroy(GTK_WIDGET(track));
}

/*                     DEF: fingerprint_callback
 * Previously function fingerPrint(int box).
 * Show the fingerprint of the clone on which the 'Fingerprint'
 * option was selected from the right-click menu*/
static void
fingerprint_callback(GtkWidget *widget, GtkTrack *track){
  addfp(track->data.cloneList[track->focusdata].index,0);
  if(bands)
    drawfpdata(1);
  graphPop();
}

/*                     DEF: gel_callback
 * Previously function gelPrint(int box).
 * Show the gel image of the clone on which the 'Gel'
 * option was selected from the right-click menu*/
static void
gel_callback(GtkWidget *widget, GtkTrack *track){
  addgel(track->data.cloneList[track->focusdata].index,0);
  gelredraw();
  graphPop();
}

/*                     DEF: select_clone_callback
 * Select the clone on which the 'Select' option was
 * selected from the right-click menu.*/
static void
select_clone_callback(GtkWidget *widget, GtkTrack *track){
  int index;

  index=track->focusdata;
  if(track->data.cloneList[index].high & SELECTED_MASK){
    /* Clone was selected; now clear*/
    track->data.cloneList[index].high ^= SELECTED_MASK;
    arrp(acedata, track->data.cloneList[index].index, CLONE)->selected=FALSE;
    entity_highlight(track, index, CLEAR1);
  }
  else
    gtk_track_highlight_clone_selected(track, index);
}
/*
static void
seq_cycle_callback(GtkWidget *widget, GtkTrack *track){
  if (  track->data.seqList[track->focusdata].cycle == 0) {
     track->data.seqList[track->focusdata].cycle = 1;
     track->data.seqList[track->focusdata].nclicks = 0;
     entity_highlight(track,track->focusdata,SEQUENCE_ACTIVE);
  }
  else if (  track->data.seqList[track->focusdata].cycle == 1) {
     track->data.seqList[track->focusdata].cycle = 0;
     track->data.seqList[track->focusdata].nclicks = 0;
     entity_highlight(track,track->focusdata,SEQUENCE_ACTIVE);
  }
    
}
*/

/*                     DEF: toggle_anchor_bin_viewing
 * Turn the viewing of the anchor bins next to the anchor
 * names on and off in the anchor track*/
static void
toggle_anchor_bin_viewing(GtkWidget *widget, GtkTrack *track){
  char str[50];

  track->show_anchor_bins = !track->show_anchor_bins;
  if(track->show_anchor_bins)
    sprintf(str, "Hide anchor %s", Proj.anchor_label);
  else
    sprintf(str, "Show anchor %s", Proj.anchor_label);

  gtk_label_set_text(GTK_LABEL(GTK_BIN(widget)->child), str);

  gtk_track_clear_data(track);
  gtk_track_fill_data(track);
  compute_track_size(track);
  glbl_show_anchor_bins=track->show_anchor_bins;    /*fred 2/26/04*/
}

/*                     DEF: toggle_anchor_pos_viewing
 * Turn the viewing of the anchor position next to the anchor
 * names on and off in the anchor track*/
static void
toggle_anchor_pos_viewing(GtkWidget *widget, GtkTrack *track){
  char str[50];

  track->show_anchor_pos = !track->show_anchor_pos;
  if(track->show_anchor_pos)
    sprintf(str, "Hide anchor positions");
  else
    sprintf(str, "Show anchor positions");

  gtk_label_set_text(GTK_LABEL(GTK_BIN(widget)->child), str);

  gtk_track_clear_data(track);
  gtk_track_fill_data(track);
  compute_track_size(track);
  glbl_show_anchor_pos=track->show_anchor_pos;     /*fred 2/26/04*/
}

/*                     DEF: toggle_anchor_line_viewing
 * Turn the viewing of the vertical 'anchor' line for each
 * anchor on and off in the anchor track*/
static void
toggle_anchor_line_viewing(GtkWidget *widget, GtkTrack *track){
  char str[50];

  track->show_anchor_lines = !track->show_anchor_lines;
  if(track->show_anchor_lines)
    sprintf(str, "Hide anchor lines");
  else
    sprintf(str, "Show anchor lines");

  gtk_label_set_text(GTK_LABEL(GTK_BIN(widget)->child), str);

  gtk_track_clear_data(track);
  gtk_track_fill_data(track);
  compute_track_size(track);
  glbl_show_anchor_lines=track->show_anchor_lines;    /*fred 2/26/04*/
}



/************* Begin track edit functions *************/
/* These functions deal with the data in the track and
 * the drawing of the data.*/

/*Entity-specific functions*/

/*                     DEF: get_clone_filter_text
 * For clone tracks.
 *Get the fields of fptr and write them to the text array*/
static void
get_clone_filter_text(struct filters *fptr, gchar **text){
  strcpy(text[0],fptr->name);
  strcpy(text[1],fptr->remark);
  switch(fptr->type){
    case ANY_CLONE:
      strcpy(text[2],"[Any]");
      break;
    case BAC_CLONE:
      strcpy(text[2],"BAC");
      break;
    case CLONE_CLONE:
      strcpy(text[2],"Clone");
      break;
    case COSMID_CLONE:
      strcpy(text[2],"Cosmid");
      break;
    case FOSMID_CLONE:
      strcpy(text[2],"Fosmid");
      break;
    case PAC_CLONE:
      strcpy(text[2],"PAC");
      break;
    case SEQ_CLONE:
      strcpy(text[2],"Sequence");
      break;
    case YAC_CLONE:
      strcpy(text[2],"YAC");
      break;
    case PARENT_CLONE:
      strcpy(text[2],"Parent");
      break;
    case PSPARENT_CLONE:
      strcpy(text[2],"Pseudo Parent");
      break;
    case EXACT_CLONE:
      strcpy(text[2],"Exact");
      break;
    case APPROX_CLONE:
      strcpy(text[2],"Approximate");
      break;
    case PSEUDO_CLONE:
      strcpy(text[2],"Pseudo Buried");
      break;
  }

  switch(fptr->status){
    case ANY_STATUS:
      strcpy(text[3],"[Any]");
      break;
    case NONE_STATUS:
      strcpy(text[3],"None");
      break;
    case TILE_STATUS:
      strcpy(text[3],"Tile");
      break;
    case SENT_STATUS:
      strcpy(text[3],"Sent");
      break;
    case READY_STATUS:
      strcpy(text[3],"Ready");
      break;
    case SHOTGUN_STATUS:
      strcpy(text[3],"Shotgun");
      break;
    case FINISHED_STATUS:
      strcpy(text[3],"Finished");
      break;
    case SD_STATUS:
      strcpy(text[3],"SD");
      break;
    case CANCELLED_STATUS:
      strcpy(text[3],"Cancelled");
      break;
  }

  switch(fptr->color_choice){
    case HIDE_COLOR:
      strcpy(text[4],"Invisible");
      break;
    case BLACK_COLOR:
      strcpy(text[4],"Black");
      break;
    case RED_COLOR:
      strcpy(text[4],"Red");
      break;
    case ORANGE_COLOR:
      strcpy(text[4],"Orange");
      break;
    case YELLOW_COLOR:
      strcpy(text[4],"Yellow");
      break;
    case GREEN_COLOR:
      strcpy(text[4],"Green");
      break;
    case BLUE_COLOR:
      strcpy(text[4],"Blue");
      break;
    case VIOLET_COLOR:
      strcpy(text[4],"Violet");
      break;
    case GRAY_COLOR:
      strcpy(text[4],"Gray");
      break;
    case CUSTOM_COLOR:
      strcpy(text[4],"Custom");
      break;
  }
}

/*                     DEF: get_marker_filter_text
 * For marker tracks.
 *Get the fields of fptr and write them to the text array*/
static void
get_marker_filter_text(struct filters *fptr, gchar **text){
  strcpy(text[0],fptr->name);
  strcpy(text[1],fptr->remark);
  switch(fptr->type){
    case ANY_MARK:
      strcpy(text[2],"[Any]");
      break;
    case BAC_MARK:
      strcpy(text[2],"BAC");
      break;
    case CDNA_MARK:
      strcpy(text[2],"cDNA");
      break;
    case CLONE_MARK:
      strcpy(text[2],"Clone");
      break;
    case COSMID_MARK:
      strcpy(text[2],"Cosmid");
      break;
    case EBAC_MARK:
      strcpy(text[2],"eBAC");
      break;
    case EMRK_MARK:
      strcpy(text[2],"eMrk");
      break;
    case END_MARK:
      strcpy(text[2],"End");
      break;
    case FOSMID_MARK:
      strcpy(text[2],"Fosmid");
      break;
    case LOCUS_MARK:
      strcpy(text[2],"Locus");
      break;
    case OVERGO_MARK:
      strcpy(text[2],"Overgo");
      break;
    case PAC_MARK:
      strcpy(text[2],"PAC");
      break;
    case PCR_MARK:
      strcpy(text[2],"PCR");
      break;
    case PROBE_MARK:
      strcpy(text[2],"Probe");
      break;
    case REPEAT_MARK:
      strcpy(text[2],"Repeat");
      break;
    case RFLP_MARK:
      strcpy(text[2],"RFLP");
      break;
    case SNP_MARK:
      strcpy(text[2],"SNP");
      break;
    case SSR_MARK:
      strcpy(text[2],"SSR");
      break;
    case STS_MARK:
      strcpy(text[2],"STS");
      break;
    case TC_MARK:
      strcpy(text[2],"TC");
      break;
    case YAC_MARK:
      strcpy(text[2],"YAC");
      break;
    case FRAME_MARK:
      strcpy(text[2],"Framework");
      break;
    case PLACE_MARK:
      strcpy(text[2],"Placement");
      break;
  }
  switch(fptr->attachment){
    case ANY_ATTACH:
      strcpy(text[3],"[Any]");
      break;
    case ONECLONE_ATTACH:
      strcpy(text[3],"One Clone");
      break;
    case MULTCTG_ATTACH:
      strcpy(text[3],"Mult Ctg");
      break;
  }
  switch(fptr->color_choice){
    case HIDE_COLOR:
      strcpy(text[4],"Invisible");
      break;
    case BLACK_COLOR:
      strcpy(text[4],"Black");
      break;
    case RED_COLOR:
      strcpy(text[4],"Red");
      break;
    case ORANGE_COLOR:
      strcpy(text[4],"Orange");
      break;
    case YELLOW_COLOR:
      strcpy(text[4],"Yellow");
      break;
    case GREEN_COLOR:
      strcpy(text[4],"Green");
      break;
    case BLUE_COLOR:
      strcpy(text[4],"Blue");
      break;
    case VIOLET_COLOR:
      strcpy(text[4],"Violet");
      break;
    case GRAY_COLOR:
      strcpy(text[4],"Gray");
      break;
    case CUSTOM_COLOR:
      strcpy(text[4],"Custom");
      break;
  }
}

/*                     DEF: get_remark_filter_text
 * For remark tracks.
 *Get the fields of fptr and write them to the text array*/
static void
get_remark_filter_text(struct filters *fptr, gchar **text){
  strcpy(text[0],fptr->name);
  switch(fptr->type){
    case ANY_REMARK:
      strcpy(text[1],"[Any]");
      break;
    case CLONE_REMARK:
      strcpy(text[1],"Clone Remarks");
      break;
    case CLONE_FPREMARK:
      strcpy(text[1],"Clone Fp Remarks");
      break;
    case MARKER_REMARK:
      strcpy(text[1],"Marker Remarks");
      break;
  }

  switch(fptr->color_choice){
    case HIDE_COLOR:
      strcpy(text[2],"Invisible");
      break;
    case BLACK_COLOR:
      strcpy(text[2],"Black");
      break;
    case RED_COLOR:
      strcpy(text[2],"Red");
      break;
    case ORANGE_COLOR:
      strcpy(text[2],"Orange");
      break;
    case YELLOW_COLOR:
      strcpy(text[2],"Yellow");
      break;
    case GREEN_COLOR:
      strcpy(text[2],"Green");
      break;
    case BLUE_COLOR:
      strcpy(text[2],"Blue");
      break;
    case VIOLET_COLOR:
      strcpy(text[2],"Violet");
      break;
    case GRAY_COLOR:
      strcpy(text[2],"Gray");
      break;
    case CUSTOM_COLOR:
      strcpy(text[2],"Custom");
      break;
  }
}

/*                     DEF: get_anchor_filter_text
 * For anchor tracks.
 *Get the fields of fptr and write them to the text array*/
static void
get_anchor_filter_text(struct filters *fptr, gchar **text){
  strcpy(text[0],fptr->name);
  switch(fptr->type){
    case ANY_ANCHOR:
      strcpy(text[1],"[Any]");
      break;
    case FRAME_ANCHOR:
      strcpy(text[1],"Framework");
      break;
    case PLACE_ANCHOR:
      strcpy(text[1],"Placement");
      break;
  }

  switch(fptr->chrom){
    case ANY_CHROM:
      strcpy(text[2],"[Any]");
      break;
    case GOOD_CHROM:
      strcpy(text[2],"Correct");
      break;
    case BAD_CHROM:
      strcpy(text[2],"Incorrect");
      break;
  }

  switch(fptr->color_choice){
    case HIDE_COLOR:
      strcpy(text[3],"Invisible");
      break;
    case BLACK_COLOR:
      strcpy(text[3],"Black");
      break;
    case RED_COLOR:
      strcpy(text[3],"Red");
      break;
    case ORANGE_COLOR:
      strcpy(text[3],"Orange");
      break;
    case YELLOW_COLOR:
      strcpy(text[3],"Yellow");
      break;
    case GREEN_COLOR:
      strcpy(text[3],"Green");
      break;
    case BLUE_COLOR:
      strcpy(text[3],"Blue");
      break;
    case VIOLET_COLOR:
      strcpy(text[3],"Violet");
      break;
    case GRAY_COLOR:
      strcpy(text[3],"Gray");
      break;
    case CUSTOM_COLOR:
      strcpy(text[3],"Custom");
      break;
  }
}

/* Callbacks for the various Selected filter edit widgets*/

static void
clone_type_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = ANY_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "[Any]");
}

static void
clone_type_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = BAC_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "BAC");
}

static void
clone_type_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CLONE_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Clone");
}

static void
clone_type_menu_callback4(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = COSMID_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Cosmid");
}

static void
clone_type_menu_callback5(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = FOSMID_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Fosmid");
}

static void
clone_type_menu_callback6(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PAC_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "PAC");
}

static void
clone_type_menu_callback7(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = SEQ_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Sequence");
}

static void
clone_type_menu_callback8(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = YAC_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "YAC");
}

static void
clone_type_menu_callback9(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PARENT_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Parent");
}

static void
clone_type_menu_callback10(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PSPARENT_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Pseudo Parent");
}

static void
clone_type_menu_callback11(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = EXACT_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Exact");
}

static void
clone_type_menu_callback12(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = APPROX_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Approximate");
}

static void
clone_type_menu_callback13(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PSEUDO_CLONE;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Pseudo Buried");
}

static void
marker_type_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = ANY_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "[Any]");
}

static void
marker_type_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = BAC_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "BAC");
}

static void
marker_type_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CDNA_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "cDNA");
}

static void
marker_type_menu_callback4(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CLONE_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Clone");
}

static void
marker_type_menu_callback5(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = COSMID_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Cosmid");
}

static void
marker_type_menu_callback6(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = EBAC_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "eBAC");
}

static void
marker_type_menu_callback7(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = EMRK_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "eMrk");
}

static void
marker_type_menu_callback8(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = END_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "End");
}

static void
marker_type_menu_callback9(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = FOSMID_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Fosmid");
}

static void
marker_type_menu_callback10(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = LOCUS_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Locus");
}

static void
marker_type_menu_callback11(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = OVERGO_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Overgo");
}

static void
marker_type_menu_callback12(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PAC_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "PAC");
}

static void
marker_type_menu_callback13(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PCR_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "PCR");
}

static void
marker_type_menu_callback14(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PROBE_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Probe");
}

static void
marker_type_menu_callback15(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = REPEAT_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Repeat");
}

static void
marker_type_menu_callback16(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = RFLP_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "RFLP");
}

static void
marker_type_menu_callback17(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = SNP_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "SNP");
}

static void
marker_type_menu_callback18(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = SSR_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "SSR");
}

static void
marker_type_menu_callback19(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = STS_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "STS");
}

static void
marker_type_menu_callback20(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = TC_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "TC");
}

static void
marker_type_menu_callback21(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = YAC_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "YAC");
}

static void
marker_type_menu_callback22(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = FRAME_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Framework");
}

static void
marker_type_menu_callback23(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PLACE_MARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Placement");
}
static void
sequence_type_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = ANY_SEQ;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "[Any]");
}

static void
sequence_type_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = DRAFT_SEQ;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Draft");
}

static void
sequence_type_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CLONE_SEQ;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Clone");
}

static void
sequence_type_menu_callback4(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = REVERSED_SEQ;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Reversed");
}

static void
marker_attach_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->attachment = ANY_ATTACH;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "[Any]");
}

static void
marker_attach_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->attachment = ONECLONE_ATTACH;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "One Clone");
}

static void
marker_attach_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->attachment = MULTCTG_ATTACH;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Mult Ctg");
}

static void
remark_type_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = ANY_REMARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "[Any]");
}

static void
remark_type_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CLONE_REMARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "Clone Remarks");
}

static void
remark_type_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = CLONE_FPREMARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "Clone Fp Remarks");
}

static void
remark_type_menu_callback4(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = MARKER_REMARK;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "Marker Remarks");
}

static void
anchor_type_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = ANY_ANCHOR;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "[Any]");
}

static void
anchor_type_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = FRAME_ANCHOR;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "Framework");
}

static void
anchor_type_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->type = PLACE_ANCHOR;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,1,
                     "Placement");
}

static void
anchor_chrom_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->chrom = ANY_CHROM;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "[Any]");
}

static void
anchor_chrom_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->chrom = GOOD_CHROM;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Correct");
}

static void
anchor_chrom_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->chrom = BAD_CHROM;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,2,
                     "Incorrect");
}

static void
clone_status_menu_callback1(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = ANY_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "[Any]");
}

static void
clone_status_menu_callback2(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = NONE_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "None");
}

static void
clone_status_menu_callback3(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = TILE_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Tile");
}

static void
clone_status_menu_callback4(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = SENT_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Sent");
}

static void
clone_status_menu_callback5(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = READY_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Ready");
}

static void
clone_status_menu_callback6(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = SHOTGUN_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Shotgun");
}

static void
clone_status_menu_callback7(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = FINISHED_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Finished");
}

static void
clone_status_menu_callback9(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = SD_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "SD");
}

static void
clone_status_menu_callback8(GtkWidget *widget, GtkTrack *t){
  if(t->current_filter->ignore){
    add_to_filterList(t);
  }
  t->current_filter->status = CANCELLED_STATUS;
  gtk_clist_set_text(GTK_CLIST(t->filter_clist),t->selected_filter,3,
                     "Cancelled");
}

/* Functions common among all entities*/

static void
name_entry_callback(GtkWidget *widget, GtkTrack *track){
  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  strcpy(track->current_filter->name, gtk_entry_get_text(GTK_ENTRY(widget)));
  gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,0,
		     track->current_filter->name);
}

static void
remark_entry_callback(GtkWidget *widget, GtkTrack *track){
  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  strcpy(track->current_filter->remark, gtk_entry_get_text(GTK_ENTRY(widget)));
  gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,1,
                     track->current_filter->remark);
}

static void
black_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("black", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=BLACK_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Black");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Black");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Black");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Black");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }
}

static void
red_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("red", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=RED_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Red");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Red");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Red");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Red");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }
}

static void
orange_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("orange", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=ORANGE_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Orange");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Orange");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Orange");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Orange");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

static void
yellow_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("yellow", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=YELLOW_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Yellow");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Yellow");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Yellow");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Yellow");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

static void
green_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("green", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=GREEN_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Green");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Green");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Green");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Green");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

static void
blue_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("blue", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=BLUE_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Blue");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Blue");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Blue");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Blue");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

static void
violet_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("violet", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=VIOLET_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Violet");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Violet");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Violet");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Violet");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

static void
gray_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  if(gdk_color_parse("gray", &(filter->color))){
    if(!gdk_colormap_alloc_color(track->colormap, &(filter->color), FALSE, TRUE)){
      g_warning("Could not allocate color");
    }
  }
  else{
    g_warning("Could not allocate color");
  }
  filter->color_choice=GRAY_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Gray");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Gray");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Gray");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Gray");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}


static int
colorseldlg_ok_callback(GtkWidget *widget, GtkTrack *track){
   gdouble color[3];
   GdkColormap *colormap;
   struct filters *filter;
   GtkStyle *style, *default_style;

   if(track->current_filter->ignore){
     add_to_filterList(track);
   }
   colormap = track->colormap;
   filter=track->current_filter;

   gtk_color_selection_get_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(track->colorseldlg)->colorsel),color);

   filter->color.red = (guint16)(color[0]*65535.0);
   filter->color.green = (guint16)(color[1]*65535.0);
   filter->color.blue = (guint16)(color[2]*65535.0);

   if(!gdk_colormap_alloc_color(colormap, &(filter->color), FALSE, TRUE)){
     g_warning("Could not allocate color");
   }

   /* Replace old Custom menu item with new of selected color*/
   gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
   track->custom_item = gtk_menu_item_new_with_label ("Custom...");
   default_style = gtk_widget_get_default_style();
   style = gtk_style_copy(default_style);
   style->fg[GTK_STATE_NORMAL] = filter->color;
   style->fg[GTK_STATE_PRELIGHT] = filter->color;
   gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
   gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
                       GTK_SIGNAL_FUNC (custom_color_callback),
                       track);
   gtk_widget_show(track->custom_item);
   gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
   gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);

   track->current_filter->color_choice=CUSTOM_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Custom");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Custom");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Custom");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Custom");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

   gtk_widget_destroy(GTK_WIDGET(track->colorseldlg));
   return TRUE;
}

static int
colorseldlg_cancel_callback(GtkWidget *widget, GtkTrack *track){
   gtk_widget_destroy(GTK_WIDGET(track->colorseldlg));
   return TRUE;
}

static void
custom_color_callback(GtkWidget *widget, GtkTrack *track){

  track->colorseldlg = gtk_color_selection_dialog_new("Select custom color");
  gtk_signal_connect(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(track->colorseldlg)->ok_button), "clicked",
                     GTK_SIGNAL_FUNC(colorseldlg_ok_callback),
                     GTK_TRACK(track));
  gtk_signal_connect(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(track->colorseldlg)->cancel_button), "clicked",
                     GTK_SIGNAL_FUNC(colorseldlg_cancel_callback),
                     track);
  gtk_widget_show(track->colorseldlg);
}

static void
hide_color_callback(GtkWidget *widget, GtkTrack *track){
  struct filters *filter;

  if(track->current_filter->ignore){
    add_to_filterList(track);
  }
  filter=track->current_filter;
  filter->color_choice=HIDE_COLOR;
  switch(track->entity){
    case CLONES:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Invisible");
      break;
    case MARKERS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,4,
                         "Invisible");
      break;
    case REMARKS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,2,
                         "Invisible");
      break;
    case ANCHORS:
      gtk_clist_set_text(GTK_CLIST(track->filter_clist),track->selected_filter,3,
                         "Invisible");
      break;
    case SEQUENCE:
    case NONE:
      break;
  }

}

/*                     DEF: remove_filter
 * Delete the selected filter*/
static void
remove_filter(GtkWidget *widget, GtkTrack *track){
  int row, i;
  struct filters *ptr, *temp;

  row=track->selected_filter;
  if(row==-1) return;

  /* Remove filter from track*/
  if(row==0){
    if(track->filterList->ignore) return;
    temp=track->filterList;
    track->filterList=track->filterList->next;
    g_free(temp);
  }
  else{
    ptr=track->filterList;
    for(i=0;i<row-1;i++){  /*Go to one before the one to delete*/
      ptr=ptr->next;
      if(ptr==NULL){ printf("ERROR -- not that many filters\n"); return;}
    }
    if(ptr->next->ignore) return;
    temp=ptr->next;
    if(temp==NULL){ printf("ERROR -- not that many filters\n"); return;}
    ptr->next=ptr->next->next;
    g_free(temp);
  }

  /* Remove filter from clist*/
  gtk_clist_remove(GTK_CLIST(track->filter_clist), row);

  if(track->filterList!=NULL){  /*Set next selection*/
    if(row!=0){
      row--;
      track->selected_filter=row;
      gtk_clist_moveto(GTK_CLIST(track->filter_clist),row,0,.5,0);
      gtk_clist_select_row(GTK_CLIST(track->filter_clist), row, 0);
    }
    else{
      gtk_clist_moveto(GTK_CLIST(track->filter_clist),row,0,.5,0);
      gtk_clist_select_row(GTK_CLIST(track->filter_clist), row, 0);
    }
  }
  else{
    track->selected_filter=-1;
  }
}

/* Functions requiring track entity to be specified*/

/*                     DEF: filter_row_move_callback
 * The back-end of the drag-and-drop rearrangement
 * feature of the filter list.  Modifies the data structures
 * to reflect the ordering in the list.*/
static void
filter_row_move_callback(GtkWidget *clist, gint src, gint dest,
                               GtkTrack *track){
  struct filters *fptr, *fptr2, *prev=NULL, *temp;
  int i;
  int numrows;

  gtk_clist_freeze(GTK_CLIST(clist));
  numrows=GTK_CLIST(clist)->rows;
  if(dest >= (numrows - 1)){
    dest--;
    /* Don't allow moving of a filter past the dummy filter)*/
    gtk_signal_handler_block_by_func(GTK_OBJECT (clist),
				     GTK_SIGNAL_FUNC(filter_row_move_callback),
				     track);
    gtk_clist_swap_rows(GTK_CLIST(clist), numrows-2, numrows-1);
    gtk_signal_handler_unblock_by_func(GTK_OBJECT (clist),
				       GTK_SIGNAL_FUNC(filter_row_move_callback),
				       track);
  }
  if(numrows<=2){
    gtk_clist_thaw(GTK_CLIST(clist));
    return;
  }

  for(fptr=track->filterList, i=0;(!fptr->next->ignore) && (i+1<src);fptr=fptr->next, i++)
    ;
  if(src!=0){
    prev=fptr;
    fptr=fptr->next;
  }

  if(fptr->ignore){
    /* Don't allow moving of an ignored filter (i.e. the dummy filter)*/
    gtk_signal_handler_block_by_func(GTK_OBJECT (clist),
				     GTK_SIGNAL_FUNC(filter_row_move_callback),
				     track);
    gtk_clist_row_move(GTK_CLIST(clist), dest, src);
    gtk_signal_handler_unblock_by_func(GTK_OBJECT (clist),
				       GTK_SIGNAL_FUNC(filter_row_move_callback),
				       track);
  }
  else{
    /* Remove filter from old spot*/
    if(src==0) track->filterList = fptr->next;
    else prev->next = fptr->next;
    for(fptr2=track->filterList, i=0;(!fptr2->next->ignore) && (i+1<dest);fptr2=fptr2->next, i++)
      ;
    /* Insert filter into new spot*/
    if(dest==0){
      temp=track->filterList;
      track->filterList=fptr;
      fptr->next=temp;
    }
    else{
      temp=fptr2->next;
      fptr2->next=fptr;
      fptr->next=temp;
    }
  }
  gtk_clist_thaw(GTK_CLIST(clist));
}

/*                     DEF: clone_filter_select_callback
 * For clone tracks.
 * Handles the selection of filters and the setting of the
 * widgets in the Seleted Filter Edit box*/
static void
clone_filter_select_callback(GtkWidget *clist, gint row, gint column,
                             GdkEventButton *event, GtkTrack *track){
  int i;
  struct filters *fptr;
  GtkStyle *style;

  gtk_signal_handler_block_by_func(GTK_OBJECT (track->name_entry),
                                   GTK_SIGNAL_FUNC(name_entry_callback),
                                   track);
  gtk_signal_handler_block_by_func(GTK_OBJECT (track->remark_entry),
                                   GTK_SIGNAL_FUNC(remark_entry_callback),
                                   track);

  if(track!=NULL) track->selected_filter=row;
  for(fptr=track->filterList, i=0;(fptr!=NULL) && (i!=row);fptr=fptr->next, i++)
    ;
  if(fptr!=NULL){
    gtk_entry_set_text(GTK_ENTRY(track->name_entry),fptr->name);
    gtk_entry_set_text(GTK_ENTRY(track->remark_entry),fptr->remark);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu),
                                (fptr->type < PARENT_CLONE) ? fptr->type : fptr->type+1);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->status_optionmenu), fptr->status);
    if(fptr->color_choice==CUSTOM_COLOR){
      gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
      track->custom_item = gtk_menu_item_new_with_label ("Custom...");
      style = gtk_style_copy(gtk_widget_get_default_style());
      style->fg[GTK_STATE_NORMAL] = fptr->color;
      style->fg[GTK_STATE_PRELIGHT] = fptr->color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
      gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
			 GTK_SIGNAL_FUNC (custom_color_callback),
			 track);
      gtk_widget_show(track->custom_item);
      gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
      gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);
    }
    else{
      gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), fptr->color_choice);
    }
    track->current_filter=fptr;
  }

  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->name_entry),
                                     GTK_SIGNAL_FUNC(name_entry_callback),
                                     track);
  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->remark_entry),
                                     GTK_SIGNAL_FUNC(remark_entry_callback),
                                     track);
}

/*                     DEF: marker_filter_select_callback
 * For marker tracks.
 * Handles the selection of filters and the setting of the
 * widgets in the Seleted Filter Edit box*/
static void
marker_filter_select_callback(GtkWidget *clist, gint row, gint column,
                              GdkEventButton *event, GtkTrack *track){
  int i;
  struct filters *fptr;
  GtkStyle *style;

  gtk_signal_handler_block_by_func(GTK_OBJECT (track->name_entry),
                                   GTK_SIGNAL_FUNC(name_entry_callback),
                                   track);
  gtk_signal_handler_block_by_func(GTK_OBJECT (track->remark_entry),
                                   GTK_SIGNAL_FUNC(remark_entry_callback),
                                   track);

  if(track!=NULL) track->selected_filter=row;
  for(fptr=track->filterList, i=0;(fptr!=NULL) && (i!=row);fptr=fptr->next, i++)
    ;
  if(fptr!=NULL){
    gtk_entry_set_text(GTK_ENTRY(track->name_entry),fptr->name);
    gtk_entry_set_text(GTK_ENTRY(track->remark_entry),fptr->remark);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), fptr->type);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->attach_optionmenu), fptr->attachment);
    if(fptr->color_choice==CUSTOM_COLOR){
      gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
      track->custom_item = gtk_menu_item_new_with_label ("Custom...");
      style = gtk_style_copy(gtk_widget_get_default_style());
      style->fg[GTK_STATE_NORMAL] = fptr->color;
      style->fg[GTK_STATE_PRELIGHT] = fptr->color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
      gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
			 GTK_SIGNAL_FUNC (custom_color_callback),
			 track);
      gtk_widget_show(track->custom_item);
      gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
      gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);
    }
    else{
      gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), fptr->color_choice);
    }
    track->current_filter=fptr;
  }

  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->name_entry),
                                     GTK_SIGNAL_FUNC(name_entry_callback),
                                     track);
  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->remark_entry),
                                     GTK_SIGNAL_FUNC(remark_entry_callback),
                                     track);
}

static void
sequence_filter_select_callback(GtkWidget *clist, gint row, gint column,
                              GdkEventButton *event, GtkTrack *track){
  int i;
  struct filters *fptr;
  GtkStyle *style;

  gtk_signal_handler_block_by_func(GTK_OBJECT (track->name_entry),
                                   GTK_SIGNAL_FUNC(name_entry_callback),
                                   track);
 
  if(track!=NULL) track->selected_filter=row;
  for(fptr=track->filterList, i=0;(fptr!=NULL) && (i!=row);fptr=fptr->next, i++)
    ;
  if(fptr!=NULL){
    gtk_entry_set_text(GTK_ENTRY(track->name_entry),fptr->name);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), fptr->type);
    if(fptr->color_choice==CUSTOM_COLOR){
      gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
      track->custom_item = gtk_menu_item_new_with_label ("Custom...");
      style = gtk_style_copy(gtk_widget_get_default_style());
      style->fg[GTK_STATE_NORMAL] = fptr->color;
      style->fg[GTK_STATE_PRELIGHT] = fptr->color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
      gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
			 GTK_SIGNAL_FUNC (custom_color_callback),
			 track);
      gtk_widget_show(track->custom_item);
      gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
      gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);
    }
    else{
      gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), fptr->color_choice);
    }
    track->current_filter=fptr;
  }

  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->name_entry),
                                     GTK_SIGNAL_FUNC(name_entry_callback),
                                     track);

}

/*                     DEF: remark_filter_select_callback
 * For remark tracks.
 * Handles the selection of filters and the setting of the
 * widgets in the Seleted Filter Edit box*/
static void
remark_filter_select_callback(GtkWidget *clist, gint row, gint column,
                              GdkEventButton *event, GtkTrack *track){
  int i;
  struct filters *fptr;
  GtkStyle *style;

  gtk_signal_handler_block_by_func(GTK_OBJECT (track->name_entry),
                                   GTK_SIGNAL_FUNC(name_entry_callback),
                                   track);

  if(track!=NULL) track->selected_filter=row;
  for(fptr=track->filterList, i=0;(fptr!=NULL) && (i!=row);fptr=fptr->next, i++)
    ;
  if(fptr!=NULL){
    gtk_entry_set_text(GTK_ENTRY(track->name_entry),fptr->name);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), fptr->type);
    if(fptr->color_choice==CUSTOM_COLOR){
      gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
      track->custom_item = gtk_menu_item_new_with_label ("Custom...");
      style = gtk_style_copy(gtk_widget_get_default_style());
      style->fg[GTK_STATE_NORMAL] = fptr->color;
      style->fg[GTK_STATE_PRELIGHT] = fptr->color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
      gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
			 GTK_SIGNAL_FUNC (custom_color_callback),
			 track);
      gtk_widget_show(track->custom_item);
      gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
      gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);
    }
    else{
      gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), fptr->color_choice);
    }
    track->current_filter=fptr;
  }

  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->name_entry),
                                     GTK_SIGNAL_FUNC(name_entry_callback),
                                     track);
}

/*                     DEF: anchor_filter_select_callback
 * For anchor tracks.
 * Handles the selection of filters and the setting of the
 * widgets in the Seleted Filter Edit box*/
static void
anchor_filter_select_callback(GtkWidget *clist, gint row, gint column,
                              GdkEventButton *event, GtkTrack *track){
  int i;
  struct filters *fptr;
  GtkStyle *style;

  gtk_signal_handler_block_by_func(GTK_OBJECT (track->name_entry),
                                   GTK_SIGNAL_FUNC(name_entry_callback),
                                   track);

  if(track!=NULL) track->selected_filter=row;
  for(fptr=track->filterList, i=0;(fptr!=NULL) && (i!=row);fptr=fptr->next, i++)
    ;
  if(fptr!=NULL){
    gtk_entry_set_text(GTK_ENTRY(track->name_entry),fptr->name);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), fptr->type);
    gtk_option_menu_set_history(GTK_OPTION_MENU (track->chrom_optionmenu), fptr->chrom);
    if(fptr->color_choice==CUSTOM_COLOR){
      gtk_container_remove (GTK_CONTAINER (track->color_menu), track->custom_item);
      track->custom_item = gtk_menu_item_new_with_label ("Custom...");
      style = gtk_style_copy(gtk_widget_get_default_style());
      style->fg[GTK_STATE_NORMAL] = fptr->color;
      style->fg[GTK_STATE_PRELIGHT] = fptr->color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
      gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
			 GTK_SIGNAL_FUNC (custom_color_callback),
			 track);
      gtk_widget_show(track->custom_item);
      gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);
      gtk_option_menu_set_history(GTK_OPTION_MENU(track->color_optionmenu),CUSTOM_COLOR);
    }
    else{
      gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), fptr->color_choice);
    }
    track->current_filter=fptr;
  }

  gtk_signal_handler_unblock_by_func(GTK_OBJECT (track->name_entry),
                                     GTK_SIGNAL_FUNC(name_entry_callback),
                                     track);
}

/*                     DEF: order_tracks_by_pos
 * Comparison routine for qsort of the tracks in the contig display*/
static int
order_tracks_by_pos(GtkWidget **t1, GtkWidget **t2){
  if(GTK_TRACK(*t1)->track_pos < GTK_TRACK(*t2)->track_pos) return -1;
  if(GTK_TRACK(*t1)->track_pos > GTK_TRACK(*t2)->track_pos) return 1;
  return 0;
}

/*                     DEF: update_track_pos
 * Callback for when the Track position in the ETP changes*/
static void
update_track_pos(GtkWidget *widget, GtkTrack *track){
  int newpos;

  newpos=GTK_ADJUSTMENT(widget)->value;
  if(newpos>track_num)  /* Possible if tracks have been deleted*/
    track->track_pos_new = track_num;
  else
    track->track_pos_new = newpos;
}

/*                     DEF: auto_rows_callback
 *                     DEF: fit_rows_callback
 *                     DEF: limit_rows_callback
 * The next three functions are callbacks for the row policy
 * in the ETP.*/
static void
auto_rows_callback(GtkWidget *widget, GtkTrack *track){
  if(GTK_TOGGLE_BUTTON (widget)->active){
    track->row_policy = AUTO_POLICY;
  }
}

static void
fit_rows_callback(GtkWidget *widget, GtkTrack *track){
  if(GTK_TOGGLE_BUTTON (widget)->active){
    track->row_policy = FIT_POLICY;
  }
}

static void
limit_rows_callback(GtkWidget *widget, GtkTrack *track){
  if(GTK_TOGGLE_BUTTON (widget)->active){
    track->row_policy = LIMIT_POLICY;
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }
  else{
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
}

/*                     DEF: update_numrows
 * Callback for the number of rows for the 'Limit' row policy*/
static void
update_numrows(GtkWidget *widget, GtkTrack *track){
  track->numrows=GTK_ADJUSTMENT(widget)->value;
}

/*                     DEF: refresh_track
 * Called when an 'Apply' is clicked.  Reorders tracks if
 * necessary. */
static void
refresh_track(GtkTrack *track){
   int i, oldpos, newpos;

   if(track->entity==CLONES)
     track->rowspacing = 20;
   else if(track->entity==SEQUENCE)
     track->rowspacing = 50;
   else
     track->rowspacing = 15;

   if(track->track_pos != track->track_pos_new){
      oldpos=track->track_pos;
      newpos=track->track_pos_new;
      if(newpos>oldpos){
        for(i=oldpos+1;i<=newpos;i++){
 	  GTK_TRACK(tracks[i-1])->track_pos--;
 	  GTK_TRACK(tracks[i-1])->track_pos_new--;
        }
      }
      else if(newpos<oldpos){
        for(i=newpos;i<oldpos;i++){
  	  GTK_TRACK(tracks[i-1])->track_pos++;
  	  GTK_TRACK(tracks[i-1])->track_pos_new++;
        }
      }
      track->track_pos=newpos;

      qsort(tracks, track_num, sizeof(GtkWidget *), (void *) order_tracks_by_pos);
      reorder_tracks();    /* Redraw tracks with new order*/
   }
   else{
     gtk_track_clear_data(track);
     gtk_track_fill_data(track);
     compute_track_size(track);
     draw_entities(track);
   }
}

/*                     DEF: copy_filter_contents
 * Make a copy of the filter in case 'Cancel' is clicked after editing*/
static void
copy_filter_contents(struct filters *dest, struct filters *src){
  *dest = *src;
}

/*                     DEF: copy_track_properties_to_temp
 * Copy items changeable by user through Edit Track Properties to tmp space,
 * so we can retrieve the originals in case Cancel is clicked.
 */
static void
copy_track_properties_to_temp(GtkTrack *t){
  struct filters *fptr, *tmp_fptr=NULL, *new_fptr;

  for(fptr=t->filterList; fptr!=NULL; fptr=fptr->next){
    new_fptr = (struct filters *) malloc(sizeof(struct filters));
    copy_filter_contents(new_fptr, fptr);
    if(tmp_fptr==NULL){
      t->tmp_filterList=new_fptr;
      tmp_fptr=t->tmp_filterList;
    }
    else{
      tmp_fptr->next=new_fptr;
      tmp_fptr=tmp_fptr->next;
    }
  }
  t->tmp_row_policy = t->row_policy;
  t->tmp_numrows = t->numrows;
}

/*                     DEF: free_filters
 * Free filter memory.*/
static void
free_filters(struct filters *p){
  struct filters *fptr, *prev;

  fptr=p;
  while(fptr!=NULL){
    prev=fptr;
    fptr=fptr->next;
    g_free(prev);
  }
  p=NULL;
}

/*                     DEF: copy_track_properties_from_temp
 * Cancel was clicked (or the close button at top).  Revert to orginals.*/
static void
copy_track_properties_from_temp(GtkTrack *t){
  struct filters *fptr, *tmp_fptr=NULL, *new_fptr;

  /* Free old list*/
  free_filters(t->filterList);

  /* Copy in new list*/
  for(fptr=t->tmp_filterList; fptr!=NULL; fptr=fptr->next){
    new_fptr = (struct filters *) malloc(sizeof(struct filters));
    copy_filter_contents(new_fptr, fptr);
    if(tmp_fptr==NULL){
      t->filterList=new_fptr;
      tmp_fptr=t->filterList;
    }
    else{
      tmp_fptr->next=new_fptr;
      tmp_fptr=tmp_fptr->next;
    }
  }

  /* Free tmp list*/
  free_filters(t->tmp_filterList);

  t->row_policy = t->tmp_row_policy;
  t->numrows = t->tmp_numrows;
}

/*                     DEF: apply_callback
 * 'Apply' button callback*/
static void
apply_callback(GtkWidget *widget, GtkTrack *track){
  free_filters(track->tmp_filterList);  /* Remove backup filter list*/
  refresh_track(track);
  copy_track_properties_to_temp(track);
}

/*                     DEF: apply_close_callback
 * 'Apply & Close' button callback*/
static void
apply_close_callback(GtkWidget *widget, GtkTrack *track){
  free_filters(track->tmp_filterList);  /* Remove backup filter list*/
  refresh_track(track);
  gtk_signal_handler_block_by_func(GTK_OBJECT (track->edit_track_window),
                                   GTK_SIGNAL_FUNC(destroy_edit_track_callback),
                                   track);
  gtk_widget_destroy(track->edit_track_window);
  track->edit_track_window=NULL;
}

/*                     DEF: cancel_edit_track_callback
 * 'Cancel' button callback*/
static void
cancel_edit_track_callback(GtkWidget *widget, GtkTrack *track){
  gtk_widget_destroy(track->edit_track_window);
  track->edit_track_window=NULL;
}

/*                     DEF: destroy_edit_track_callback
 * Handler for the 'destroy' signal for the ETP window*/
static void
destroy_edit_track_callback(GtkWidget *widget, GtkTrack *track){
  copy_track_properties_from_temp(track);
  track->edit_track_window=NULL;
}

/*                     DEF: clone_edit_track
 * Graphics for the clone Edit Track Properties (ETP) window*/
static void
clone_edit_track(GtkTrack *track){
  GtkWidget *main_vbox;
  GtkWidget *hbox, *hbox2, *hbox3;
  GtkWidget *vbox, *vbox2;
  GtkWidget *label;
  /* Clone type menu items*/
  GtkWidget *any1;
  GtkWidget *bac1;
  GtkWidget *clone1;
  GtkWidget *cosmid1;
  GtkWidget *fosmid1;
  GtkWidget *pac1;
  GtkWidget *seq1;
  GtkWidget *yac1;
  GtkWidget *spacer1;  /* Space between clone types and bury types */
  GtkWidget *parent1;
  GtkWidget *psparent1;
  GtkWidget *exact1;
  GtkWidget *approx1;
  GtkWidget *pseudo1;
  /* Sequence status menu items*/
  GtkWidget *any2;
  GtkWidget *none1;
  GtkWidget *tile1;
  GtkWidget *sent1;
  GtkWidget *ready1;
  GtkWidget *shotgun1;
  GtkWidget *finished1;
  GtkWidget *sd1;
  GtkWidget *cancelled1;

  /*Color menu items*/
  GtkWidget *black_item;
  GtkWidget *red_item;
  GtkWidget *orange_item;
  GtkWidget *yellow_item;
  GtkWidget *green_item;
  GtkWidget *blue_item;
  GtkWidget *violet_item;
  GtkWidget *gray_item;
  /* Custom item is in track because it gets redone when color changes*/
  GtkWidget *hide_item;

  GdkColor color;
  GdkColormap *colormap;
  GtkStyle *style, *default_style;

  GtkWidget *scrolled_window;
  gchar *titles[]= {"Clone Substring", "Remark Substring", "Type", "Status", "Color"};
  GtkObject *pos_adj;
  GtkWidget *pos_spin_button;
  GtkObject *row_adj;
  GtkWidget *radiobutton1;
  GtkWidget *radiobutton2;
  GtkWidget *radiobutton3;
  GtkWidget *help_button;
  GtkWidget *remove_filter_button;
  GtkWidget *cancel_button;
  GtkWidget *apply_button;
  GtkWidget *apply_close_button;
  GtkWidget *frame1;
  GtkTooltips *tooltips;
  struct filters *fptr;
  gchar *text[5];
  int i;

  if(track->edit_track_window!=NULL){
    gdk_window_raise(track->edit_track_window->window);
    return;
  }

  copy_track_properties_to_temp(track);

  tooltips = gtk_tooltips_new ();
  track->edit_track_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (track->edit_track_window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_track_callback), track);
  gtk_container_set_border_width (GTK_CONTAINER (track->edit_track_window), 5);
  gtk_window_set_title (GTK_WINDOW (track->edit_track_window), "Edit Track Properties");

  main_vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(track->edit_track_window), main_vbox);

  /* Filter clist*/
  hbox=gtk_hbox_new(FALSE, 5);
  label=gtk_label_new("Filters in Use:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  pos_adj=gtk_adjustment_new(track->track_pos,1,track_num,-1,-1,0);
  pos_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(pos_adj),.5,0);
  gtk_box_pack_end (GTK_BOX (hbox), pos_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (pos_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_track_pos), track);
  label=gtk_label_new("Track position");
  gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(TRUE, 5);
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  track->filter_clist=gtk_clist_new_with_titles(5,titles);
  gtk_clist_set_reorderable(GTK_CLIST(track->filter_clist), TRUE);
  gtk_signal_connect(GTK_OBJECT(track->filter_clist), "select_row",
		     GTK_SIGNAL_FUNC(clone_filter_select_callback),
		     track);
  gtk_signal_connect_after(GTK_OBJECT(track->filter_clist), "row_move",
		     GTK_SIGNAL_FUNC(filter_row_move_callback),
		     track);
  gtk_clist_column_titles_passive(GTK_CLIST(track->filter_clist));
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),0,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),1,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),2,125);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),3,95);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),4,80);

  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),track->filter_clist);
  gtk_widget_set_usize(scrolled_window,580,125);
  gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, TRUE, TRUE, 0);

  /* Filter edit; also for new filter*/
  frame1 = gtk_frame_new("Selected Filter Edit");
  gtk_box_pack_start(GTK_BOX(main_vbox), frame1, FALSE, FALSE, 0);
  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  hbox=gtk_hbox_new(FALSE, 5);

  /* Filter on name*/
  track->name_entry = gtk_entry_new_with_max_length(CLONE_SZ);
  gtk_signal_connect (GTK_OBJECT (track->name_entry), "changed",
		      GTK_SIGNAL_FUNC (name_entry_callback),
		      track);
  gtk_tooltips_set_tip (tooltips, track->name_entry, "Enter substring", NULL);
  gtk_box_pack_start(GTK_BOX(hbox), track->name_entry, FALSE, FALSE, 0);

  /* Filter on remark*/
  track->remark_entry = gtk_entry_new_with_max_length(COMMENT_SZ);
  gtk_signal_connect (GTK_OBJECT (track->remark_entry), "changed",
		      GTK_SIGNAL_FUNC (remark_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->remark_entry, FALSE, FALSE, 0);

  /* Filter on type*/
  track->type_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->type_optionmenu, FALSE, FALSE, 0);
  track->type_menu=gtk_menu_new();

  any1 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback1),
		      track);
  gtk_widget_show(any1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), any1);

  bac1 = gtk_menu_item_new_with_label ("BAC");
  gtk_signal_connect (GTK_OBJECT (bac1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback2),
		      track);
  gtk_widget_show(bac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), bac1);

  clone1 = gtk_menu_item_new_with_label ("Clone");
  gtk_signal_connect (GTK_OBJECT (clone1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback3),
		      track);
  gtk_widget_show(clone1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), clone1);

  cosmid1 = gtk_menu_item_new_with_label ("Cosmid");
  gtk_signal_connect (GTK_OBJECT (cosmid1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback4),
		      track);
  gtk_widget_show(cosmid1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), cosmid1);

  fosmid1 = gtk_menu_item_new_with_label ("Fosmid");
  gtk_signal_connect (GTK_OBJECT (fosmid1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback5),
		      track);
  gtk_widget_show(fosmid1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), fosmid1);

  pac1 = gtk_menu_item_new_with_label ("PAC");
  gtk_signal_connect (GTK_OBJECT (pac1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback6),
		      track);
  gtk_widget_show(pac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), pac1);

  seq1 = gtk_menu_item_new_with_label ("Sequence");
  gtk_signal_connect (GTK_OBJECT (seq1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback7),
		      track);
  gtk_widget_show(seq1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), seq1);

  yac1 = gtk_menu_item_new_with_label ("YAC");
  gtk_signal_connect (GTK_OBJECT (yac1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback8),
		      track);
  gtk_widget_show(yac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), yac1);

  spacer1 = gtk_menu_item_new_with_label ("-----------");
  gtk_widget_set_sensitive(spacer1, FALSE);
  gtk_widget_show(spacer1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), spacer1);

  parent1 = gtk_menu_item_new_with_label ("Parent");
  gtk_signal_connect (GTK_OBJECT (parent1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback9),
		      track);
  gtk_widget_show(parent1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), parent1);

  psparent1 = gtk_menu_item_new_with_label ("Pseudo Parent");
  gtk_signal_connect (GTK_OBJECT (psparent1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback10),
		      track);
  gtk_widget_show(psparent1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), psparent1);

  exact1 = gtk_menu_item_new_with_label ("Exact");
  gtk_signal_connect (GTK_OBJECT (exact1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback11),
		      track);
  gtk_widget_show(exact1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), exact1);

  approx1 = gtk_menu_item_new_with_label ("Approximate");
  gtk_signal_connect (GTK_OBJECT (approx1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback12),
		      track);
  gtk_widget_show(approx1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), approx1);

  pseudo1 = gtk_menu_item_new_with_label ("Pseudo Buried");
  gtk_signal_connect (GTK_OBJECT (pseudo1), "activate",
		      GTK_SIGNAL_FUNC (clone_type_menu_callback13),
		      track);
  gtk_widget_show(pseudo1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), pseudo1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->type_optionmenu), track->type_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), 0);

  /* Filter on sequence status*/
  track->status_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->status_optionmenu, FALSE, FALSE, 0);
  track->status_menu=gtk_menu_new();

  any2 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any2), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback1),
		      track);
  gtk_widget_show(any2);
  gtk_container_add (GTK_CONTAINER (track->status_menu), any2);

  none1 = gtk_menu_item_new_with_label ("None");
  gtk_signal_connect (GTK_OBJECT (none1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback2),
		      track);
  gtk_widget_show(none1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), none1);

  tile1 = gtk_menu_item_new_with_label ("Tile");
  gtk_signal_connect (GTK_OBJECT (tile1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback3),
		      track);
  gtk_widget_show(tile1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), tile1);

  sent1 = gtk_menu_item_new_with_label ("Sent");
  gtk_signal_connect (GTK_OBJECT (sent1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback4),
		      track);
  gtk_widget_show(sent1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), sent1);

  ready1 = gtk_menu_item_new_with_label ("Ready");
  gtk_signal_connect (GTK_OBJECT (ready1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback5),
		      track);
  gtk_widget_show(ready1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), ready1);

  shotgun1 = gtk_menu_item_new_with_label ("Shotgun");
  gtk_signal_connect (GTK_OBJECT (shotgun1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback6),
		      track);
  gtk_widget_show(shotgun1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), shotgun1);

  finished1 = gtk_menu_item_new_with_label ("Finished");
  gtk_signal_connect (GTK_OBJECT (finished1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback7),
		      track);
  gtk_widget_show(finished1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), finished1);

  sd1 = gtk_menu_item_new_with_label ("SD");
  gtk_signal_connect (GTK_OBJECT (sd1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback9),
		      track);
  gtk_widget_show(sd1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), sd1);


  cancelled1 = gtk_menu_item_new_with_label ("Cancelled");
  gtk_signal_connect (GTK_OBJECT (cancelled1), "activate",
		      GTK_SIGNAL_FUNC (clone_status_menu_callback8),
		      track);
  gtk_widget_show(cancelled1);
  gtk_container_add (GTK_CONTAINER (track->status_menu), cancelled1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->status_optionmenu), track->status_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->status_optionmenu), 0);

  /* Which color to show entities in*/
  track->color_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->color_optionmenu, TRUE, TRUE, 0);

  track->color_menu=gtk_menu_new();
  colormap=track->colormap;
  default_style = gtk_widget_get_default_style();

  hide_item = gtk_menu_item_new_with_label ("Invisible");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(hide_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (hide_item), "activate",
		      GTK_SIGNAL_FUNC (hide_color_callback),
		      track);
  gtk_widget_show(hide_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), hide_item);

  black_item = gtk_menu_item_new_with_label ("Black");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(black_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (black_item), "activate",
		      GTK_SIGNAL_FUNC (black_color_callback),
		      track);
  gtk_widget_show(black_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), black_item);

  red_item = gtk_menu_item_new_with_label ("Red");
  if(gdk_color_parse("red", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(red_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (red_item), "activate",
		      GTK_SIGNAL_FUNC (red_color_callback),
		      track);
  gtk_widget_show(red_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), red_item);

  orange_item = gtk_menu_item_new_with_label ("Orange");
  if(gdk_color_parse("orange", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(orange_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (orange_item), "activate",
		      GTK_SIGNAL_FUNC (orange_color_callback),
		      track);
  gtk_widget_show(orange_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), orange_item);

  yellow_item = gtk_menu_item_new_with_label ("Yellow");
  if(gdk_color_parse("yellow", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(yellow_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (yellow_item), "activate",
		      GTK_SIGNAL_FUNC (yellow_color_callback),
		      track);
  gtk_widget_show(yellow_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), yellow_item);

  green_item = gtk_menu_item_new_with_label ("Green");
  if(gdk_color_parse("green", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(green_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (green_item), "activate",
		      GTK_SIGNAL_FUNC (green_color_callback),
		      track);
  gtk_widget_show(green_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), green_item);

  blue_item = gtk_menu_item_new_with_label ("Blue");
  if(gdk_color_parse("blue", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(blue_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (blue_item), "activate",
		      GTK_SIGNAL_FUNC (blue_color_callback),
		      track);
  gtk_widget_show(blue_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), blue_item);

  violet_item = gtk_menu_item_new_with_label ("Violet");
  if(gdk_color_parse("violet", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(violet_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (violet_item), "activate",
		      GTK_SIGNAL_FUNC (violet_color_callback),
		      track);
  gtk_widget_show(violet_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), violet_item);

  gray_item = gtk_menu_item_new_with_label ("Gray");
  if(gdk_color_parse("gray", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(gray_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (gray_item), "activate",
		      GTK_SIGNAL_FUNC (gray_color_callback),
		      track);
  gtk_widget_show(gray_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), gray_item);

  track->custom_item = gtk_menu_item_new_with_label ("Custom...");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
    }
  }
  gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
		      GTK_SIGNAL_FUNC (custom_color_callback),
		      track);
  gtk_widget_show(track->custom_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->color_optionmenu), track->color_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), BLACK_COLOR);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(FALSE, 5);
  remove_filter_button=gtk_button_new_with_label("Remove Filter");
  gtk_signal_connect(GTK_OBJECT(remove_filter_button), "clicked",
		     GTK_SIGNAL_FUNC(remove_filter),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox), remove_filter_button, TRUE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), vbox);

  /* Row policy*/
  hbox=gtk_hbox_new(FALSE, 5);

  vbox=gtk_vbox_new(FALSE, 5);
  frame1 = gtk_frame_new("Row Policy");
  gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  radiobutton1 = gtk_radio_button_new_with_label(NULL, "Automatic");
  gtk_signal_connect (GTK_OBJECT (radiobutton1), "clicked",
                      GTK_SIGNAL_FUNC (auto_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton1, FALSE, FALSE, 0);

  radiobutton2 = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton1)),
                                                 "Fit");
  gtk_signal_connect(GTK_OBJECT(radiobutton2), "clicked",
		     GTK_SIGNAL_FUNC(fit_rows_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);

  hbox3=gtk_hbox_new(FALSE, 5);
  row_adj=gtk_adjustment_new(track->numrows,1,50,1,1,0);
  radiobutton3=gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton2)),
                                               "Limit rows to:");
  gtk_signal_connect (GTK_OBJECT (radiobutton3), "clicked",
                      GTK_SIGNAL_FUNC (limit_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0);
  track->row_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(row_adj),.5,0);
  gtk_box_pack_start (GTK_BOX (hbox3), track->row_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (row_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_numrows), track);
  gtk_box_pack_start (GTK_BOX (hbox2), hbox3, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), hbox2);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

  /* Buttons*/
  vbox2=gtk_vbox_new(FALSE, 5);
  hbox2=gtk_hbox_new(FALSE, 5);
  help_button=gtk_button_new_with_label("Help");
  gtk_signal_connect (GTK_OBJECT (help_button), "clicked",
		      GTK_SIGNAL_FUNC (clone_edit_help), NULL);
  gtk_box_pack_start (GTK_BOX (hbox2), help_button, FALSE, FALSE, 0);
  cancel_button=gtk_button_new_with_label("Close");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_edit_track_callback), track);
  gtk_box_pack_start (GTK_BOX (hbox2), cancel_button, FALSE, FALSE, 0);
  apply_button=gtk_button_new_with_label("Apply");
  gtk_signal_connect(GTK_OBJECT(apply_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_button, FALSE, FALSE, 0);
  apply_close_button=gtk_button_new_with_label("Apply & Close");
  gtk_signal_connect(GTK_OBJECT(apply_close_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_close_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_close_button, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 5);

  /* Set values*/
  for(i=0;i<5;i++) text[i] = (gchar *) malloc(sizeof(char[50]));
  for(fptr=track->filterList;fptr!=NULL;fptr=fptr->next){
    if(fptr->ignore) continue;
    get_clone_filter_text(fptr, text);
    gtk_clist_append(GTK_CLIST(track->filter_clist), text);
  }
  strcpy(text[0],"[Select to add filter]");
  strcpy(text[1],"");
  strcpy(text[2],"");
  strcpy(text[3],"");
  strcpy(text[4],"");
  gtk_clist_append(GTK_CLIST(track->filter_clist), text);

  for(i=0;i<5;i++) g_free(text[i]);

  gtk_clist_select_row(GTK_CLIST(track->filter_clist),
                       GTK_CLIST(track->filter_clist)->rows-1,0);

  if(track->row_policy==AUTO_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton1), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==FIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==LIMIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton3), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }

  gtk_widget_show_all(track->edit_track_window);
}

/*                     DEF: marker_edit_track
 * Graphics for the marker Edit Track Properties (ETP) window*/
static void
marker_edit_track(GtkTrack *track){
  GtkWidget *main_vbox;
  GtkWidget *hbox, *hbox2, *hbox3;
  GtkWidget *vbox, *vbox2;
  GtkWidget *label;
  /* Marker type menu items*/
  GtkWidget *any1;
  GtkWidget *bac1;
  GtkWidget *cdna1;
  GtkWidget *clone1;
  GtkWidget *cosmid1;
  GtkWidget *ebac1;
  GtkWidget *emrk1;
  GtkWidget *end1;
  GtkWidget *fosmid1;
  GtkWidget *locus1;
  GtkWidget *overgo1;
  GtkWidget *pac1;
  GtkWidget *pcr1;
  GtkWidget *probe1;
  GtkWidget *repeat1;
  GtkWidget *rflp1;
  GtkWidget *snp1;
  GtkWidget *ssr1;
  GtkWidget *sts1;
  GtkWidget *tc1;
  GtkWidget *yac1;
  GtkWidget *spacer1;
  GtkWidget *framework1;
  GtkWidget *placement1;

  /*Attachment menu items*/
  GtkWidget *any2;
  GtkWidget *oneclone1;
  GtkWidget *multctg1;

  /*Color menu items*/
  GtkWidget *black_item;
  GtkWidget *red_item;
  GtkWidget *orange_item;
  GtkWidget *yellow_item;
  GtkWidget *green_item;
  GtkWidget *blue_item;
  GtkWidget *violet_item;
  GtkWidget *gray_item;
  /* Custom item is in track because it gets redone when color changes*/
  GtkWidget *hide_item;

  GdkColor color;
  GdkColormap *colormap;
  GtkStyle *style, *default_style;

  GtkWidget *scrolled_window;
  gchar *titles[]= {"Marker Substring", "Remark Substring", "Type", "Attachment", "Color"};
  GtkObject *pos_adj;
  GtkWidget *pos_spin_button;
  GtkObject *row_adj;
  GtkWidget *radiobutton1;
  GtkWidget *radiobutton2;
  GtkWidget *radiobutton3;
  GtkWidget *remove_filter_button;
  GtkWidget *help_button;
  GtkWidget *cancel_button;
  GtkWidget *apply_button;
  GtkWidget *apply_close_button;
  GtkWidget *frame1;
  struct filters *fptr;
  gchar *text[10];
  int i;

  if(track->edit_track_window!=NULL){
    gdk_window_raise(track->edit_track_window->window);
    return;
  }

  copy_track_properties_to_temp(track);

  track->edit_track_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (track->edit_track_window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_track_callback), track);
  gtk_container_set_border_width (GTK_CONTAINER (track->edit_track_window), 5);
  gtk_window_set_title (GTK_WINDOW (track->edit_track_window), "Edit Track Properties");

  main_vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(track->edit_track_window), main_vbox);

  /* Filter clist*/
  hbox=gtk_hbox_new(FALSE, 5);
  label=gtk_label_new("Filters in Use:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);

  pos_adj=gtk_adjustment_new(track->track_pos,1,track_num,-1,-1,0);
  pos_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(pos_adj),.5,0);
  gtk_box_pack_end (GTK_BOX (hbox), pos_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (pos_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_track_pos), track);
  label=gtk_label_new("Track position");
  gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(TRUE, 5);
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  track->filter_clist=gtk_clist_new_with_titles(5,titles);
  gtk_clist_set_reorderable(GTK_CLIST(track->filter_clist), TRUE);
  gtk_signal_connect(GTK_OBJECT(track->filter_clist), "select_row",
		     GTK_SIGNAL_FUNC(marker_filter_select_callback),
		     track);
  gtk_signal_connect_after(GTK_OBJECT(track->filter_clist), "row_move",
		     GTK_SIGNAL_FUNC(filter_row_move_callback),
		     track);
  gtk_clist_column_titles_passive(GTK_CLIST(track->filter_clist));
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),0,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),1,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),2,105);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),3,105);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),4,80);

  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),track->filter_clist);
  gtk_widget_set_usize(scrolled_window,615,125);
  gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, TRUE, TRUE, 0);

  /* Filter edit; also for new filter*/
  frame1 = gtk_frame_new("Selected Filter Edit");
  gtk_box_pack_start(GTK_BOX(main_vbox), frame1, FALSE, FALSE, 0);
  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  hbox=gtk_hbox_new(FALSE, 5);

  /* Filter on name*/
  track->name_entry = gtk_entry_new_with_max_length(CLONE_SZ);
  gtk_signal_connect (GTK_OBJECT (track->name_entry), "changed",
		      GTK_SIGNAL_FUNC (name_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->name_entry, FALSE, FALSE, 0);

  /* Filter on remark*/
  track->remark_entry = gtk_entry_new_with_max_length(COMMENT_SZ);
  gtk_signal_connect (GTK_OBJECT (track->remark_entry), "changed",
		      GTK_SIGNAL_FUNC (remark_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->remark_entry, FALSE, FALSE, 0);

  /* Filter on type*/
  track->type_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->type_optionmenu, FALSE, FALSE, 0);
  track->type_menu=gtk_menu_new();

  any1 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback1),
		      track);
  gtk_widget_show(any1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), any1);

  bac1 = gtk_menu_item_new_with_label ("BAC");
  gtk_signal_connect (GTK_OBJECT (bac1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback2),
		      track);
  gtk_widget_show(bac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), bac1);

  cdna1 = gtk_menu_item_new_with_label ("cDNA");
  gtk_signal_connect (GTK_OBJECT (cdna1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback3),
		      track);
  gtk_widget_show(cdna1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), cdna1);

  clone1 = gtk_menu_item_new_with_label ("Clone");
  gtk_signal_connect (GTK_OBJECT (clone1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback4),
		      track);
  gtk_widget_show(clone1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), clone1);

  cosmid1 = gtk_menu_item_new_with_label ("Cosmid");
  gtk_signal_connect (GTK_OBJECT (cosmid1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback5),
		      track);
  gtk_widget_show(cosmid1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), cosmid1);

  ebac1 = gtk_menu_item_new_with_label ("eBAC");
  gtk_signal_connect (GTK_OBJECT (ebac1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback6),
		      track);
  gtk_widget_show(ebac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), ebac1);

  emrk1 = gtk_menu_item_new_with_label ("eMrk");
  gtk_signal_connect (GTK_OBJECT (emrk1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback7),
		      track);
  gtk_widget_show(emrk1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), emrk1);

  end1 = gtk_menu_item_new_with_label ("End");
  gtk_signal_connect (GTK_OBJECT (end1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback8),
		      track);
  gtk_widget_show(end1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), end1);

  fosmid1 = gtk_menu_item_new_with_label ("Fosmid");
  gtk_signal_connect (GTK_OBJECT (fosmid1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback9),
		      track);
  gtk_widget_show(fosmid1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), fosmid1);

  locus1 = gtk_menu_item_new_with_label ("Locus");
  gtk_signal_connect (GTK_OBJECT (locus1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback10),
		      track);
  gtk_widget_show(locus1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), locus1);

  overgo1 = gtk_menu_item_new_with_label ("Overgo");
  gtk_signal_connect (GTK_OBJECT (overgo1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback11),
		      track);
  gtk_widget_show(overgo1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), overgo1);

  pac1 = gtk_menu_item_new_with_label ("PAC");
  gtk_signal_connect (GTK_OBJECT (pac1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback12),
		      track);
  gtk_widget_show(pac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), pac1);

  pcr1 = gtk_menu_item_new_with_label ("PCR");
  gtk_signal_connect (GTK_OBJECT (pcr1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback13),
		      track);
  gtk_widget_show(pcr1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), pcr1);

  probe1 = gtk_menu_item_new_with_label ("Probe");
  gtk_signal_connect (GTK_OBJECT (probe1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback14),
		      track);
  gtk_widget_show(probe1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), probe1);

  repeat1 = gtk_menu_item_new_with_label ("Repeat");
  gtk_signal_connect (GTK_OBJECT (repeat1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback15),
		      track);
  gtk_widget_show(repeat1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), repeat1);

  rflp1 = gtk_menu_item_new_with_label ("RFLP");
  gtk_signal_connect (GTK_OBJECT (rflp1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback16),
		      track);
  gtk_widget_show(rflp1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), rflp1);

  snp1 = gtk_menu_item_new_with_label ("SNP");
  gtk_signal_connect (GTK_OBJECT (snp1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback17),
		      track);
  gtk_widget_show(snp1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), snp1);

  ssr1 = gtk_menu_item_new_with_label ("SSR");
  gtk_signal_connect (GTK_OBJECT (ssr1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback18),
		      track);
  gtk_widget_show(ssr1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), ssr1);

  sts1 = gtk_menu_item_new_with_label ("STS");
  gtk_signal_connect (GTK_OBJECT (sts1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback19),
		      track);
  gtk_widget_show(sts1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), sts1);

  tc1 = gtk_menu_item_new_with_label ("TC");
  gtk_signal_connect (GTK_OBJECT (tc1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback20),
		      track);
  gtk_widget_show(tc1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), tc1);

  yac1 = gtk_menu_item_new_with_label ("YAC");
  gtk_signal_connect (GTK_OBJECT (yac1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback21),
		      track);
  gtk_widget_show(yac1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), yac1);

  spacer1 = gtk_menu_item_new_with_label ("--------");
  gtk_widget_set_sensitive(spacer1, FALSE);
  gtk_widget_show(spacer1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), spacer1);

  framework1 = gtk_menu_item_new_with_label ("Framework");
  gtk_signal_connect (GTK_OBJECT (framework1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback22),
		      track);
  gtk_widget_show(framework1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), framework1);

  placement1 = gtk_menu_item_new_with_label ("Placement");
  gtk_signal_connect (GTK_OBJECT (placement1), "activate",
		      GTK_SIGNAL_FUNC (marker_type_menu_callback23),
		      track);
  gtk_widget_show(placement1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), placement1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->type_optionmenu), track->type_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), 0);

  /* Filter on attachment*/
  track->attach_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->attach_optionmenu, FALSE, FALSE, 0);
  track->attach_menu=gtk_menu_new();

  any2 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any2), "activate",
		      GTK_SIGNAL_FUNC (marker_attach_menu_callback1),
		      track);
  gtk_widget_show(any2);
  gtk_container_add (GTK_CONTAINER (track->attach_menu), any2);

  oneclone1 = gtk_menu_item_new_with_label ("One Clone");
  gtk_signal_connect (GTK_OBJECT (oneclone1), "activate",
		      GTK_SIGNAL_FUNC (marker_attach_menu_callback2),
		      track);
  gtk_widget_show(oneclone1);
  gtk_container_add (GTK_CONTAINER (track->attach_menu), oneclone1);

  multctg1 = gtk_menu_item_new_with_label ("Mult Ctg");
  gtk_signal_connect (GTK_OBJECT (multctg1), "activate",
		      GTK_SIGNAL_FUNC (marker_attach_menu_callback3),
		      track);
  gtk_widget_show(multctg1);
  gtk_container_add (GTK_CONTAINER (track->attach_menu), multctg1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->attach_optionmenu), track->attach_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->attach_optionmenu), 0);

  /* Which color to show entities in*/
  track->color_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->color_optionmenu, TRUE, TRUE, 0);

  track->color_menu=gtk_menu_new();
  colormap=track->colormap;
  default_style = gtk_widget_get_default_style();

  hide_item = gtk_menu_item_new_with_label ("Invisible");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(hide_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (hide_item), "activate",
		      GTK_SIGNAL_FUNC (hide_color_callback),
		      track);
  gtk_widget_show(hide_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), hide_item);

  black_item = gtk_menu_item_new_with_label ("Black");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(black_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (black_item), "activate",
		      GTK_SIGNAL_FUNC (black_color_callback),
		      track);
  gtk_widget_show(black_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), black_item);

  red_item = gtk_menu_item_new_with_label ("Red");
  if(gdk_color_parse("red", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(red_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (red_item), "activate",
		      GTK_SIGNAL_FUNC (red_color_callback),
		      track);
  gtk_widget_show(red_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), red_item);

  orange_item = gtk_menu_item_new_with_label ("Orange");
  if(gdk_color_parse("orange", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(orange_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (orange_item), "activate",
		      GTK_SIGNAL_FUNC (orange_color_callback),
		      track);
  gtk_widget_show(orange_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), orange_item);

  yellow_item = gtk_menu_item_new_with_label ("Yellow");
  if(gdk_color_parse("yellow", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(yellow_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (yellow_item), "activate",
		      GTK_SIGNAL_FUNC (yellow_color_callback),
		      track);
  gtk_widget_show(yellow_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), yellow_item);

  green_item = gtk_menu_item_new_with_label ("Green");
  if(gdk_color_parse("green", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(green_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (green_item), "activate",
		      GTK_SIGNAL_FUNC (green_color_callback),
		      track);
  gtk_widget_show(green_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), green_item);

  blue_item = gtk_menu_item_new_with_label ("Blue");
  if(gdk_color_parse("blue", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(blue_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (blue_item), "activate",
		      GTK_SIGNAL_FUNC (blue_color_callback),
		      track);
  gtk_widget_show(blue_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), blue_item);

  violet_item = gtk_menu_item_new_with_label ("Violet");
  if(gdk_color_parse("violet", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(violet_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (violet_item), "activate",
		      GTK_SIGNAL_FUNC (violet_color_callback),
		      track);
  gtk_widget_show(violet_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), violet_item);

  gray_item = gtk_menu_item_new_with_label ("Gray");
  if(gdk_color_parse("gray", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(gray_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (gray_item), "activate",
		      GTK_SIGNAL_FUNC (gray_color_callback),
		      track);
  gtk_widget_show(gray_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), gray_item);

  track->custom_item = gtk_menu_item_new_with_label ("Custom...");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
    }
  }
  gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
		      GTK_SIGNAL_FUNC (custom_color_callback),
		      track);
  gtk_widget_show(track->custom_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->color_optionmenu), track->color_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), BLACK_COLOR);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(FALSE, 5);
  remove_filter_button=gtk_button_new_with_label("Remove Filter");
  gtk_signal_connect(GTK_OBJECT(remove_filter_button), "clicked",
		     GTK_SIGNAL_FUNC(remove_filter),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox), remove_filter_button, TRUE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), vbox);

  /* Row policy*/
  hbox=gtk_hbox_new(FALSE, 5);

  vbox=gtk_vbox_new(FALSE, 5);
  frame1 = gtk_frame_new("Row Policy");
  gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  radiobutton1 = gtk_radio_button_new_with_label(NULL, "Automatic");
  gtk_signal_connect (GTK_OBJECT (radiobutton1), "clicked",
                      GTK_SIGNAL_FUNC (auto_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton1, FALSE, FALSE, 0);

  radiobutton2 = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton1)),
                                                 "Fit");
  gtk_signal_connect(GTK_OBJECT(radiobutton2), "clicked",
		     GTK_SIGNAL_FUNC(fit_rows_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);

  hbox3=gtk_hbox_new(FALSE, 5);
  row_adj=gtk_adjustment_new(track->numrows,1,50,1,1,0);
  radiobutton3=gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton2)),
                                               "Limit rows to:");
  gtk_signal_connect (GTK_OBJECT (radiobutton3), "clicked",
                      GTK_SIGNAL_FUNC (limit_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0);
  track->row_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(row_adj),.5,0);
  gtk_box_pack_start (GTK_BOX (hbox3), track->row_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (row_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_numrows), track);
  gtk_box_pack_start (GTK_BOX (hbox2), hbox3, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), hbox2);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

  /* Buttons*/
  vbox2=gtk_vbox_new(FALSE, 5);
  hbox2=gtk_hbox_new(FALSE, 5);
  help_button=gtk_button_new_with_label("Help");
  gtk_signal_connect (GTK_OBJECT (help_button), "clicked",
		      GTK_SIGNAL_FUNC (marker_edit_help), NULL);
  gtk_box_pack_start (GTK_BOX (hbox2), help_button, FALSE, FALSE, 0);
  cancel_button=gtk_button_new_with_label("Close");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_edit_track_callback), track);
  gtk_box_pack_start (GTK_BOX (hbox2), cancel_button, FALSE, FALSE, 0);
  apply_button=gtk_button_new_with_label("Apply");
  gtk_signal_connect(GTK_OBJECT(apply_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_button, FALSE, FALSE, 0);
  apply_close_button=gtk_button_new_with_label("Apply & Close");
  gtk_signal_connect(GTK_OBJECT(apply_close_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_close_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_close_button, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 5);

  /* Set values*/
  for(i=0;i<5;i++) text[i] = (gchar *) malloc(sizeof(char[50]));
  for(fptr=track->filterList;fptr!=NULL;fptr=fptr->next){
    if(fptr->ignore) continue;
    get_marker_filter_text(fptr, text);
    gtk_clist_append(GTK_CLIST(track->filter_clist), text);
  }
  strcpy(text[0],"[Select to add filter]");
  strcpy(text[1],"");
  strcpy(text[2],"");
  strcpy(text[3],"");
  strcpy(text[4],"");
  gtk_clist_append(GTK_CLIST(track->filter_clist), text);

  for(i=0;i<5;i++) g_free(text[i]);

  gtk_clist_select_row(GTK_CLIST(track->filter_clist),
                       GTK_CLIST(track->filter_clist)->rows-1,0);

  if(track->row_policy==AUTO_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton1), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==FIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==LIMIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton3), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }

  gtk_widget_show_all(track->edit_track_window);
}

static void
sequence_edit_track(GtkTrack *track){
  GtkWidget *main_vbox;
  GtkWidget *hbox, *hbox2, *hbox3;
  GtkWidget *vbox, *vbox2;
  GtkWidget *label;
  /* Marker type menu items*/
  GtkWidget *any1;
  GtkWidget *draft;
  GtkWidget *clone;
  GtkWidget *reversed;


  /*Color menu items*/
  GtkWidget *black_item;
  GtkWidget *red_item;
  GtkWidget *orange_item;
  GtkWidget *yellow_item;
  GtkWidget *green_item;
  GtkWidget *blue_item;
  GtkWidget *violet_item;
  GtkWidget *gray_item;
  /* Custom item is in track because it gets redone when color changes*/
  GtkWidget *hide_item;

  GdkColor color;
  GdkColormap *colormap;
  GtkStyle *style, *default_style;

  GtkWidget *scrolled_window;
  gchar *titles[]= {"Sequence Substring",  "Type", "Color"};
  GtkObject *pos_adj;
  GtkWidget *pos_spin_button;
  GtkObject *row_adj;
  GtkWidget *radiobutton1;
  GtkWidget *radiobutton2;
  GtkWidget *radiobutton3;
  GtkWidget *remove_filter_button;
  GtkWidget *help_button;
  GtkWidget *cancel_button;
  GtkWidget *apply_button;
  GtkWidget *apply_close_button;
  GtkWidget *frame1;

  if(track->edit_track_window!=NULL){
    gdk_window_raise(track->edit_track_window->window);
    return;
  }

  copy_track_properties_to_temp(track);

  track->edit_track_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (track->edit_track_window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_track_callback), track);
  gtk_container_set_border_width (GTK_CONTAINER (track->edit_track_window), 5);
  gtk_window_set_title (GTK_WINDOW (track->edit_track_window), "Edit Track Properties");

  main_vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(track->edit_track_window), main_vbox);


  /* Filter clist*/
  hbox=gtk_hbox_new(FALSE, 5);

  pos_adj=gtk_adjustment_new(track->track_pos,1,track_num,-1,-1,0);
  pos_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(pos_adj),.5,0);
  gtk_box_pack_end (GTK_BOX (hbox), pos_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (pos_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_track_pos), track);
  label=gtk_label_new("Track position");
  gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);

if (0)
{
  hbox=gtk_hbox_new(TRUE, 5);
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  track->filter_clist=gtk_clist_new_with_titles(3,titles);
  gtk_clist_set_reorderable(GTK_CLIST(track->filter_clist), TRUE);
  gtk_signal_connect(GTK_OBJECT(track->filter_clist), "select_row",
		     GTK_SIGNAL_FUNC(sequence_filter_select_callback),
		     track);
  gtk_signal_connect_after(GTK_OBJECT(track->filter_clist), "row_move",
		     GTK_SIGNAL_FUNC(filter_row_move_callback),
		     track);
  gtk_clist_column_titles_passive(GTK_CLIST(track->filter_clist));
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),0,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),1,105);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),2,105);

  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),track->filter_clist);
  gtk_widget_set_usize(scrolled_window,615,125);
  gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, TRUE, TRUE, 0);

  /* Filter edit; also for new filter*/
  frame1 = gtk_frame_new("Selected Filter Edit");
  gtk_box_pack_start(GTK_BOX(main_vbox), frame1, FALSE, FALSE, 0);
  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  hbox=gtk_hbox_new(FALSE, 5);

  /* Filter on name*/
  track->name_entry = gtk_entry_new_with_max_length(CLONE_SZ);
  gtk_signal_connect (GTK_OBJECT (track->name_entry), "changed",
		      GTK_SIGNAL_FUNC (name_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->name_entry, FALSE, FALSE, 0);

  /* Filter on remark*/
  track->remark_entry = gtk_entry_new_with_max_length(COMMENT_SZ);
  gtk_signal_connect (GTK_OBJECT (track->remark_entry), "changed",
		      GTK_SIGNAL_FUNC (remark_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->remark_entry, FALSE, FALSE, 0);

  /* Filter on type*/
  track->type_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->type_optionmenu, FALSE, FALSE, 0);
  track->type_menu=gtk_menu_new();

  any1 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any1), "activate",
		      GTK_SIGNAL_FUNC (sequence_type_menu_callback1),
		      track);
  gtk_widget_show(any1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), any1);

  draft = gtk_menu_item_new_with_label ("DRAFT");
  gtk_signal_connect (GTK_OBJECT (draft), "activate",
		      GTK_SIGNAL_FUNC (sequence_type_menu_callback2),
		      track);
  gtk_widget_show(draft);
  gtk_container_add (GTK_CONTAINER (track->type_menu), draft);

  clone = gtk_menu_item_new_with_label ("CLONE");
  gtk_signal_connect (GTK_OBJECT (clone), "activate",
		      GTK_SIGNAL_FUNC (sequence_type_menu_callback3),
		      track);
  gtk_widget_show(clone);
  gtk_container_add (GTK_CONTAINER (track->type_menu), clone);

  reversed = gtk_menu_item_new_with_label ("REVERSED");
  gtk_signal_connect (GTK_OBJECT (reversed), "activate",
		      GTK_SIGNAL_FUNC (sequence_type_menu_callback4),
		      track);
  gtk_widget_show(reversed);
  gtk_container_add (GTK_CONTAINER (track->type_menu), reversed);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->type_optionmenu), track->type_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), 0);


  /* Which color to show entities in*/
  track->color_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->color_optionmenu, TRUE, TRUE, 0);

  track->color_menu=gtk_menu_new();
  colormap=track->colormap;
  default_style = gtk_widget_get_default_style();

  hide_item = gtk_menu_item_new_with_label ("Invisible");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(hide_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (hide_item), "activate",
		      GTK_SIGNAL_FUNC (hide_color_callback),
		      track);
  gtk_widget_show(hide_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), hide_item);

  black_item = gtk_menu_item_new_with_label ("Black");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(black_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (black_item), "activate",
		      GTK_SIGNAL_FUNC (black_color_callback),
		      track);
  gtk_widget_show(black_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), black_item);

  red_item = gtk_menu_item_new_with_label ("Red");
  if(gdk_color_parse("red", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(red_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (red_item), "activate",
		      GTK_SIGNAL_FUNC (red_color_callback),
		      track);
  gtk_widget_show(red_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), red_item);

  orange_item = gtk_menu_item_new_with_label ("Orange");
  if(gdk_color_parse("orange", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(orange_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (orange_item), "activate",
		      GTK_SIGNAL_FUNC (orange_color_callback),
		      track);
  gtk_widget_show(orange_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), orange_item);

  yellow_item = gtk_menu_item_new_with_label ("Yellow");
  if(gdk_color_parse("yellow", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(yellow_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (yellow_item), "activate",
		      GTK_SIGNAL_FUNC (yellow_color_callback),
		      track);
  gtk_widget_show(yellow_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), yellow_item);

  green_item = gtk_menu_item_new_with_label ("Green");
  if(gdk_color_parse("green", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(green_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (green_item), "activate",
		      GTK_SIGNAL_FUNC (green_color_callback),
		      track);
  gtk_widget_show(green_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), green_item);

  blue_item = gtk_menu_item_new_with_label ("Blue");
  if(gdk_color_parse("blue", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(blue_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (blue_item), "activate",
		      GTK_SIGNAL_FUNC (blue_color_callback),
		      track);
  gtk_widget_show(blue_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), blue_item);

  violet_item = gtk_menu_item_new_with_label ("Violet");
  if(gdk_color_parse("violet", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(violet_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (violet_item), "activate",
		      GTK_SIGNAL_FUNC (violet_color_callback),
		      track);
  gtk_widget_show(violet_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), violet_item);

  gray_item = gtk_menu_item_new_with_label ("Gray");
  if(gdk_color_parse("gray", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(gray_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (gray_item), "activate",
		      GTK_SIGNAL_FUNC (gray_color_callback),
		      track);
  gtk_widget_show(gray_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), gray_item);

  track->custom_item = gtk_menu_item_new_with_label ("Custom...");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
    }
  }
  gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
		      GTK_SIGNAL_FUNC (custom_color_callback),
		      track);
  gtk_widget_show(track->custom_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->color_optionmenu), track->color_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), BLACK_COLOR);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(FALSE, 5);
  remove_filter_button=gtk_button_new_with_label("Remove Filter");
  gtk_signal_connect(GTK_OBJECT(remove_filter_button), "clicked",
		     GTK_SIGNAL_FUNC(remove_filter),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox), remove_filter_button, TRUE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), vbox);
}
  /* Row policy*/
  hbox=gtk_hbox_new(FALSE, 5);

  vbox=gtk_vbox_new(FALSE, 5);
  frame1 = gtk_frame_new("Row Policy");
  gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  radiobutton1 = gtk_radio_button_new_with_label(NULL, "Automatic");
  gtk_signal_connect (GTK_OBJECT (radiobutton1), "clicked",
                      GTK_SIGNAL_FUNC (auto_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton1, FALSE, FALSE, 0);

  radiobutton2 = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton1)),
                                                 "Fit");
  gtk_signal_connect(GTK_OBJECT(radiobutton2), "clicked",
		     GTK_SIGNAL_FUNC(fit_rows_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);

  hbox3=gtk_hbox_new(FALSE, 5);
  row_adj=gtk_adjustment_new(track->numrows,1,50,1,1,0);
  radiobutton3=gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton2)),
                                               "Limit rows to:");
  gtk_signal_connect (GTK_OBJECT (radiobutton3), "clicked",
                      GTK_SIGNAL_FUNC (limit_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0);
  track->row_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(row_adj),.5,0);
  gtk_box_pack_start (GTK_BOX (hbox3), track->row_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (row_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_numrows), track);
  gtk_box_pack_start (GTK_BOX (hbox2), hbox3, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), hbox2);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

  /* Buttons*/
  vbox2=gtk_vbox_new(FALSE, 5);
  hbox2=gtk_hbox_new(FALSE, 5);
  help_button=gtk_button_new_with_label("Help");
  gtk_signal_connect (GTK_OBJECT (help_button), "clicked",
		      GTK_SIGNAL_FUNC (marker_edit_help), NULL);
  gtk_box_pack_start (GTK_BOX (hbox2), help_button, FALSE, FALSE, 0);
  cancel_button=gtk_button_new_with_label("Close");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_edit_track_callback), track);
  gtk_box_pack_start (GTK_BOX (hbox2), cancel_button, FALSE, FALSE, 0);
  apply_button=gtk_button_new_with_label("Apply");
  gtk_signal_connect(GTK_OBJECT(apply_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_button, FALSE, FALSE, 0);
  apply_close_button=gtk_button_new_with_label("Apply & Close");
  gtk_signal_connect(GTK_OBJECT(apply_close_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_close_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_close_button, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 5);



if (0)
{
  gtk_clist_select_row(GTK_CLIST(track->filter_clist),
                       GTK_CLIST(track->filter_clist)->rows-1,0);
}
  if(track->row_policy==AUTO_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton1), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==FIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==LIMIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton3), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }

  gtk_widget_show_all(track->edit_track_window);
}
/*                     DEF: remark_edit_track
 * Graphics for the remark Edit Track Properties (ETP) window*/
static void
remark_edit_track(GtkTrack *track){
  GtkWidget *main_vbox;
  GtkWidget *hbox, *hbox2, *hbox3;
  GtkWidget *vbox, *vbox2;
  GtkWidget *label;
  /* Remark type menu items*/
  GtkWidget *any1;
  GtkWidget *clone1;
  GtkWidget *fp1;
  GtkWidget *marker1;

  /*Color menu items*/
  GtkWidget *black_item;
  GtkWidget *red_item;
  GtkWidget *orange_item;
  GtkWidget *yellow_item;
  GtkWidget *green_item;
  GtkWidget *blue_item;
  GtkWidget *violet_item;
  GtkWidget *gray_item;
  /* Custom item is in track because it gets redone when color changes*/
  GtkWidget *hide_item;

  GdkColor color;
  GdkColormap *colormap;
  GtkStyle *style, *default_style;

  GtkWidget *scrolled_window;
  gchar *titles[]= {"Remark Substring", "Type", "Color"};
  GtkObject *pos_adj;
  GtkWidget *pos_spin_button;
  GtkObject *row_adj;
  GtkWidget *radiobutton1;
  GtkWidget *radiobutton2;
  GtkWidget *radiobutton3;
  GtkWidget *remove_filter_button;
  GtkWidget *help_button;
  GtkWidget *cancel_button;
  GtkWidget *apply_button;
  GtkWidget *apply_close_button;
  GtkWidget *frame1;
  struct filters *fptr;
  gchar *text[3];
  int i;

  if(track->edit_track_window!=NULL){
    gdk_window_raise(track->edit_track_window->window);
    return;
  }

  copy_track_properties_to_temp(track);

  track->edit_track_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (track->edit_track_window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_track_callback), track);
  gtk_container_set_border_width (GTK_CONTAINER (track->edit_track_window), 5);
  gtk_window_set_title (GTK_WINDOW (track->edit_track_window), "Edit Track Properties");

  main_vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(track->edit_track_window), main_vbox);

  /* Filter clist*/
  hbox=gtk_hbox_new(FALSE, 5);
  label=gtk_label_new("Filters in Use:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);

  pos_adj=gtk_adjustment_new(track->track_pos,1,track_num,-1,-1,0);
  pos_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(pos_adj),.5,0);
  gtk_box_pack_end (GTK_BOX (hbox), pos_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (pos_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_track_pos), track);
  label=gtk_label_new("Track position");
  gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(TRUE, 5);
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  track->filter_clist=gtk_clist_new_with_titles(3,titles);
  gtk_clist_set_reorderable(GTK_CLIST(track->filter_clist), TRUE);
  gtk_signal_connect(GTK_OBJECT(track->filter_clist), "select_row",
		     GTK_SIGNAL_FUNC(remark_filter_select_callback),
		     track);
  gtk_signal_connect_after(GTK_OBJECT(track->filter_clist), "row_move",
		     GTK_SIGNAL_FUNC(filter_row_move_callback),
		     track);
  gtk_clist_column_titles_passive(GTK_CLIST(track->filter_clist));
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),0,150);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),1,150);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),2,80);

  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),track->filter_clist);
  gtk_widget_set_usize(scrolled_window,430,125);
  gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, TRUE, TRUE, 0);

  /* Filter edit; also for new filter*/
  frame1 = gtk_frame_new("Selected Filter Edit");
  gtk_box_pack_start(GTK_BOX(main_vbox), frame1, FALSE, FALSE, 0);
  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  hbox=gtk_hbox_new(FALSE, 5);

  /* Filter on name*/
  track->name_entry = gtk_entry_new_with_max_length(CLONE_SZ);
  gtk_signal_connect (GTK_OBJECT (track->name_entry), "changed",
		      GTK_SIGNAL_FUNC (name_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->name_entry, FALSE, FALSE, 0);

  /* Filter on type*/
  track->type_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->type_optionmenu, FALSE, FALSE, 0);
  track->type_menu=gtk_menu_new();

  any1 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any1), "activate",
		      GTK_SIGNAL_FUNC (remark_type_menu_callback1),
		      track);
  gtk_widget_show(any1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), any1);

  clone1 = gtk_menu_item_new_with_label ("Clone Remarks");
  gtk_signal_connect (GTK_OBJECT (clone1), "activate",
		      GTK_SIGNAL_FUNC (remark_type_menu_callback2),
		      track);
  gtk_widget_show(clone1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), clone1);

  fp1 = gtk_menu_item_new_with_label ("Clone Fp Remarks");
  gtk_signal_connect (GTK_OBJECT (fp1), "activate",
		      GTK_SIGNAL_FUNC (remark_type_menu_callback3),
		      track);
  gtk_widget_show(fp1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), fp1);

  marker1 = gtk_menu_item_new_with_label ("Marker Remarks");
  gtk_signal_connect (GTK_OBJECT (marker1), "activate",
		      GTK_SIGNAL_FUNC (remark_type_menu_callback4),
		      track);
  gtk_widget_show(marker1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), marker1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->type_optionmenu), track->type_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), 0);

  /* Which color to show entities in*/
  track->color_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->color_optionmenu, TRUE, TRUE, 0);

  track->color_menu=gtk_menu_new();
  colormap=track->colormap;
  default_style = gtk_widget_get_default_style();

  hide_item = gtk_menu_item_new_with_label ("Invisible");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(hide_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (hide_item), "activate",
		      GTK_SIGNAL_FUNC (hide_color_callback),
		      track);
  gtk_widget_show(hide_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), hide_item);

  black_item = gtk_menu_item_new_with_label ("Black");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(black_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (black_item), "activate",
		      GTK_SIGNAL_FUNC (black_color_callback),
		      track);
  gtk_widget_show(black_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), black_item);

  red_item = gtk_menu_item_new_with_label ("Red");
  if(gdk_color_parse("red", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(red_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (red_item), "activate",
		      GTK_SIGNAL_FUNC (red_color_callback),
		      track);
  gtk_widget_show(red_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), red_item);

  orange_item = gtk_menu_item_new_with_label ("Orange");
  if(gdk_color_parse("orange", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(orange_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (orange_item), "activate",
		      GTK_SIGNAL_FUNC (orange_color_callback),
		      track);
  gtk_widget_show(orange_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), orange_item);

  yellow_item = gtk_menu_item_new_with_label ("Yellow");
  if(gdk_color_parse("yellow", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(yellow_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (yellow_item), "activate",
		      GTK_SIGNAL_FUNC (yellow_color_callback),
		      track);
  gtk_widget_show(yellow_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), yellow_item);

  green_item = gtk_menu_item_new_with_label ("Green");
  if(gdk_color_parse("green", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(green_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (green_item), "activate",
		      GTK_SIGNAL_FUNC (green_color_callback),
		      track);
  gtk_widget_show(green_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), green_item);

  blue_item = gtk_menu_item_new_with_label ("Blue");
  if(gdk_color_parse("blue", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(blue_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (blue_item), "activate",
		      GTK_SIGNAL_FUNC (blue_color_callback),
		      track);
  gtk_widget_show(blue_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), blue_item);

  violet_item = gtk_menu_item_new_with_label ("Violet");
  if(gdk_color_parse("violet", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(violet_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (violet_item), "activate",
		      GTK_SIGNAL_FUNC (violet_color_callback),
		      track);
  gtk_widget_show(violet_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), violet_item);

  gray_item = gtk_menu_item_new_with_label ("Gray");
  if(gdk_color_parse("gray", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(gray_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (gray_item), "activate",
		      GTK_SIGNAL_FUNC (gray_color_callback),
		      track);
  gtk_widget_show(gray_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), gray_item);

  track->custom_item = gtk_menu_item_new_with_label ("Custom...");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
    }
  }
  gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
		      GTK_SIGNAL_FUNC (custom_color_callback),
		      track);
  gtk_widget_show(track->custom_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->color_optionmenu), track->color_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), BLACK_COLOR);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(FALSE, 5);
  remove_filter_button=gtk_button_new_with_label("Remove Filter");
  gtk_signal_connect(GTK_OBJECT(remove_filter_button), "clicked",
		     GTK_SIGNAL_FUNC(remove_filter),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox), remove_filter_button, TRUE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), vbox);

  /* Row policy*/
  hbox=gtk_hbox_new(FALSE, 5);

  vbox=gtk_vbox_new(FALSE, 5);
  frame1 = gtk_frame_new("Row Policy");
  gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  radiobutton1 = gtk_radio_button_new_with_label(NULL, "Automatic");
  gtk_signal_connect (GTK_OBJECT (radiobutton1), "clicked",
                      GTK_SIGNAL_FUNC (auto_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton1, FALSE, FALSE, 0);

  radiobutton2 = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton1)),
                                                 "Fit");
  gtk_signal_connect(GTK_OBJECT(radiobutton2), "clicked",
		     GTK_SIGNAL_FUNC(fit_rows_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);

  hbox3=gtk_hbox_new(FALSE, 5);
  row_adj=gtk_adjustment_new(track->numrows,1,50,1,1,0);
  radiobutton3=gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton2)),
                                               "Limit rows to:");
  gtk_signal_connect (GTK_OBJECT (radiobutton3), "clicked",
                      GTK_SIGNAL_FUNC (limit_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0);
  track->row_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(row_adj),.5,0);
  gtk_box_pack_start (GTK_BOX (hbox3), track->row_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (row_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_numrows), track);
  gtk_box_pack_start (GTK_BOX (hbox2), hbox3, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), hbox2);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

  /* Buttons*/
  vbox2=gtk_vbox_new(FALSE, 5);
  hbox2=gtk_hbox_new(FALSE, 5);
  help_button=gtk_button_new_with_label("Help");
  gtk_signal_connect (GTK_OBJECT (help_button), "clicked",
		      GTK_SIGNAL_FUNC (remark_edit_help), NULL);
  gtk_box_pack_start (GTK_BOX (hbox2), help_button, FALSE, FALSE, 0);
  cancel_button=gtk_button_new_with_label("Close");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_edit_track_callback), track);
  gtk_box_pack_start (GTK_BOX (hbox2), cancel_button, FALSE, FALSE, 0);
  apply_button=gtk_button_new_with_label("Apply");
  gtk_signal_connect(GTK_OBJECT(apply_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_button, FALSE, FALSE, 0);
  apply_close_button=gtk_button_new_with_label("Apply & Close");
  gtk_signal_connect(GTK_OBJECT(apply_close_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_close_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_close_button, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 5);

  /* Set values*/
  for(i=0;i<3;i++) text[i] = (gchar *) malloc(sizeof(char[50]));
  for(fptr=track->filterList;fptr!=NULL;fptr=fptr->next){
    if(fptr->ignore) continue;
    get_remark_filter_text(fptr, text);
    gtk_clist_append(GTK_CLIST(track->filter_clist), text);
  }
  strcpy(text[0],"[Select to add filter]");
  strcpy(text[1],"");
  strcpy(text[2],"");
  gtk_clist_append(GTK_CLIST(track->filter_clist), text);

  for(i=0;i<3;i++) g_free(text[i]);

  gtk_clist_select_row(GTK_CLIST(track->filter_clist),
                       GTK_CLIST(track->filter_clist)->rows-1,0);

  if(track->row_policy==AUTO_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton1), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==FIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==LIMIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton3), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }



  gtk_widget_show_all(track->edit_track_window);
}

/*                     DEF: anchor_edit_track
 * Graphics for the anchor Edit Track Properties (ETP) window*/
static void
anchor_edit_track(GtkTrack *track){
  GtkWidget *main_vbox;
  GtkWidget *hbox, *hbox2, *hbox3;
  GtkWidget *vbox, *vbox2;
  GtkWidget *label;

  /* Anchor type menu items*/
  GtkWidget *any1;
  GtkWidget *framework1;
  GtkWidget *placement1;

  /* Chromosome assignment menu items*/
  GtkWidget *any2;
  GtkWidget *good1;
  GtkWidget *bad1;

  /*Color menu items*/
  GtkWidget *black_item;
  GtkWidget *red_item;
  GtkWidget *orange_item;
  GtkWidget *yellow_item;
  GtkWidget *green_item;
  GtkWidget *blue_item;
  GtkWidget *violet_item;
  GtkWidget *gray_item;
  /* Custom item is in track because it gets redone when color changes*/
  GtkWidget *hide_item;

  GdkColor color;
  GdkColormap *colormap;
  GtkStyle *style, *default_style;

  GtkWidget *scrolled_window;
  gchar *titles[]= {"Anchor Substring", "Type", "Chr Assignment", "Color"};
  GtkObject *pos_adj;
  GtkWidget *pos_spin_button;
  GtkObject *row_adj;
  GtkWidget *radiobutton1;
  GtkWidget *radiobutton2;
  GtkWidget *radiobutton3;
  GtkWidget *remove_filter_button;
  GtkWidget *help_button;
  GtkWidget *cancel_button;
  GtkWidget *apply_button;
  GtkWidget *apply_close_button;
  GtkWidget *frame1;
  struct filters *fptr;
  gchar *text[4];
  int i;

  if(track->edit_track_window!=NULL){
    gdk_window_raise(track->edit_track_window->window);
    return;
  }

  copy_track_properties_to_temp(track);

  track->edit_track_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect (GTK_OBJECT (track->edit_track_window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_track_callback), track);
  gtk_container_set_border_width (GTK_CONTAINER (track->edit_track_window), 5);
  gtk_window_set_title (GTK_WINDOW (track->edit_track_window), "Edit Track Properties");

  main_vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(track->edit_track_window), main_vbox);

  /* Filter clist*/
  hbox=gtk_hbox_new(FALSE, 5);
  label=gtk_label_new("Filters in Use:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);

  pos_adj=gtk_adjustment_new(track->track_pos,1,track_num,-1,-1,0);
  pos_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(pos_adj),.5,0);
  gtk_box_pack_end (GTK_BOX (hbox), pos_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (pos_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_track_pos), track);
  label=gtk_label_new("Track position");
  gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(TRUE, 5);
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  track->filter_clist=gtk_clist_new_with_titles(4,titles);
  gtk_clist_set_reorderable(GTK_CLIST(track->filter_clist), TRUE);
  gtk_signal_connect(GTK_OBJECT(track->filter_clist), "select_row",
		     GTK_SIGNAL_FUNC(anchor_filter_select_callback),
		     track);
  gtk_signal_connect_after(GTK_OBJECT(track->filter_clist), "row_move",
		     GTK_SIGNAL_FUNC(filter_row_move_callback),
		     track);
  gtk_clist_column_titles_passive(GTK_CLIST(track->filter_clist));
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),0,155);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),1,100);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),2,90);
  gtk_clist_set_column_width(GTK_CLIST(track->filter_clist),3,80);

  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_window),track->filter_clist);
  gtk_widget_set_usize(scrolled_window,505,125);
  gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, TRUE, TRUE, 0);

  /* Filter edit; also for new filter*/
  frame1 = gtk_frame_new("Selected Filter Edit");
  gtk_box_pack_start(GTK_BOX(main_vbox), frame1, FALSE, FALSE, 0);
  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);

  hbox=gtk_hbox_new(FALSE, 5);

  /* Filter on name*/
  track->name_entry = gtk_entry_new_with_max_length(CLONE_SZ);
  gtk_signal_connect (GTK_OBJECT (track->name_entry), "changed",
		      GTK_SIGNAL_FUNC (name_entry_callback),
		      track);
  gtk_box_pack_start(GTK_BOX(hbox), track->name_entry, FALSE, FALSE, 0);

  /* Filter on type*/
  track->type_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->type_optionmenu, FALSE, FALSE, 0);
  track->type_menu=gtk_menu_new();

  any1 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any1), "activate",
		      GTK_SIGNAL_FUNC (anchor_type_menu_callback1),
		      track);
  gtk_widget_show(any1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), any1);

  framework1 = gtk_menu_item_new_with_label ("Framework");
  gtk_signal_connect (GTK_OBJECT (framework1), "activate",
		      GTK_SIGNAL_FUNC (anchor_type_menu_callback2),
		      track);
  gtk_widget_show(framework1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), framework1);

  placement1 = gtk_menu_item_new_with_label ("Placement");
  gtk_signal_connect (GTK_OBJECT (placement1), "activate",
		      GTK_SIGNAL_FUNC (anchor_type_menu_callback3),
		      track);
  gtk_widget_show(placement1);
  gtk_container_add (GTK_CONTAINER (track->type_menu), placement1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->type_optionmenu), track->type_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->type_optionmenu), 0);

  /* Filter on chromosome assignment*/
  track->chrom_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->chrom_optionmenu, FALSE, FALSE, 0);
  track->chrom_menu=gtk_menu_new();

  any2 = gtk_menu_item_new_with_label ("[Any]");
  gtk_signal_connect (GTK_OBJECT (any2), "activate",
		      GTK_SIGNAL_FUNC (anchor_chrom_menu_callback1),
		      track);
  gtk_widget_show(any2);
  gtk_container_add (GTK_CONTAINER (track->chrom_menu), any2);

  good1 = gtk_menu_item_new_with_label ("Correct");
  gtk_signal_connect (GTK_OBJECT (good1), "activate",
		      GTK_SIGNAL_FUNC (anchor_chrom_menu_callback2),
		      track);
  gtk_widget_show(good1);
  gtk_container_add (GTK_CONTAINER (track->chrom_menu), good1);

  bad1 = gtk_menu_item_new_with_label ("Incorrect");
  gtk_signal_connect (GTK_OBJECT (bad1), "activate",
		      GTK_SIGNAL_FUNC (anchor_chrom_menu_callback3),
		      track);
  gtk_widget_show(bad1);
  gtk_container_add (GTK_CONTAINER (track->chrom_menu), bad1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->chrom_optionmenu), track->chrom_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->chrom_optionmenu), 0);

  /* Which color to show entities in*/
  track->color_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox), track->color_optionmenu, TRUE, TRUE, 0);

  track->color_menu=gtk_menu_new();
  colormap=track->colormap;
  default_style = gtk_widget_get_default_style();

  hide_item = gtk_menu_item_new_with_label ("Invisible");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(hide_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (hide_item), "activate",
		      GTK_SIGNAL_FUNC (hide_color_callback),
		      track);
  gtk_widget_show(hide_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), hide_item);

  black_item = gtk_menu_item_new_with_label ("Black");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(black_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (black_item), "activate",
		      GTK_SIGNAL_FUNC (black_color_callback),
		      track);
  gtk_widget_show(black_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), black_item);

  red_item = gtk_menu_item_new_with_label ("Red");
  if(gdk_color_parse("red", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(red_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (red_item), "activate",
		      GTK_SIGNAL_FUNC (red_color_callback),
		      track);
  gtk_widget_show(red_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), red_item);

  orange_item = gtk_menu_item_new_with_label ("Orange");
  if(gdk_color_parse("orange", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(orange_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (orange_item), "activate",
		      GTK_SIGNAL_FUNC (orange_color_callback),
		      track);
  gtk_widget_show(orange_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), orange_item);

  yellow_item = gtk_menu_item_new_with_label ("Yellow");
  if(gdk_color_parse("yellow", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(yellow_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (yellow_item), "activate",
		      GTK_SIGNAL_FUNC (yellow_color_callback),
		      track);
  gtk_widget_show(yellow_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), yellow_item);

  green_item = gtk_menu_item_new_with_label ("Green");
  if(gdk_color_parse("green", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(green_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (green_item), "activate",
		      GTK_SIGNAL_FUNC (green_color_callback),
		      track);
  gtk_widget_show(green_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), green_item);

  blue_item = gtk_menu_item_new_with_label ("Blue");
  if(gdk_color_parse("blue", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(blue_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (blue_item), "activate",
		      GTK_SIGNAL_FUNC (blue_color_callback),
		      track);
  gtk_widget_show(blue_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), blue_item);

  violet_item = gtk_menu_item_new_with_label ("Violet");
  if(gdk_color_parse("violet", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(violet_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (violet_item), "activate",
		      GTK_SIGNAL_FUNC (violet_color_callback),
		      track);
  gtk_widget_show(violet_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), violet_item);

  gray_item = gtk_menu_item_new_with_label ("Gray");
  if(gdk_color_parse("gray", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(gray_item)->child, style);
    }
  }
  gtk_signal_connect (GTK_OBJECT (gray_item), "activate",
		      GTK_SIGNAL_FUNC (gray_color_callback),
		      track);
  gtk_widget_show(gray_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), gray_item);

  track->custom_item = gtk_menu_item_new_with_label ("Custom...");
  if(gdk_color_parse("black", &color)){
    if(gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE)){
      style = gtk_style_copy(default_style);
      style->fg[GTK_STATE_NORMAL] = color;
      style->fg[GTK_STATE_PRELIGHT] = color;
      gtk_widget_set_style(GTK_BIN(track->custom_item)->child, style);
    }
  }
  gtk_signal_connect(GTK_OBJECT (track->custom_item), "activate",
		      GTK_SIGNAL_FUNC (custom_color_callback),
		      track);
  gtk_widget_show(track->custom_item);
  gtk_container_add (GTK_CONTAINER (track->color_menu), track->custom_item);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (track->color_optionmenu), track->color_menu);
  gtk_option_menu_set_history(GTK_OPTION_MENU (track->color_optionmenu), BLACK_COLOR);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  hbox=gtk_hbox_new(FALSE, 5);
  remove_filter_button=gtk_button_new_with_label("Remove Filter");
  gtk_signal_connect(GTK_OBJECT(remove_filter_button), "clicked",
		     GTK_SIGNAL_FUNC(remove_filter),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox), remove_filter_button, TRUE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), vbox);

  /* Row policy*/
  hbox=gtk_hbox_new(FALSE, 5);

  vbox=gtk_vbox_new(FALSE, 5);
  frame1 = gtk_frame_new("Row Policy");
  gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5);

  radiobutton1 = gtk_radio_button_new_with_label(NULL, "Automatic");
  gtk_signal_connect (GTK_OBJECT (radiobutton1), "clicked",
                      GTK_SIGNAL_FUNC (auto_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton1, FALSE, FALSE, 0);

  radiobutton2 = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton1)),
                                                 "Fit");
  gtk_signal_connect(GTK_OBJECT(radiobutton2), "clicked",
		     GTK_SIGNAL_FUNC(fit_rows_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);

  hbox3=gtk_hbox_new(FALSE, 5);
  row_adj=gtk_adjustment_new(track->numrows,1,50,1,1,0);
  radiobutton3=gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(radiobutton2)),
                                               "Limit rows to:");
  gtk_signal_connect (GTK_OBJECT (radiobutton3), "clicked",
                      GTK_SIGNAL_FUNC (limit_rows_callback),
                      track);
  gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0);
  track->row_spin_button=gtk_spin_button_new(GTK_ADJUSTMENT(row_adj),.5,0);
  gtk_box_pack_start (GTK_BOX (hbox3), track->row_spin_button, FALSE, FALSE, 0);
  gtk_signal_connect (GTK_OBJECT (row_adj), "value-changed",
		      GTK_SIGNAL_FUNC (update_numrows), track);
  gtk_box_pack_start (GTK_BOX (hbox2), hbox3, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (frame1), hbox2);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);

  /* Buttons*/
  vbox2=gtk_vbox_new(FALSE, 5);
  hbox2=gtk_hbox_new(FALSE, 5);
  help_button=gtk_button_new_with_label("Help");
  gtk_signal_connect (GTK_OBJECT (help_button), "clicked",
		      GTK_SIGNAL_FUNC (anchor_edit_help), NULL);
  gtk_box_pack_start (GTK_BOX (hbox2), help_button, FALSE, FALSE, 0);
  cancel_button=gtk_button_new_with_label("Close");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_edit_track_callback), track);
  gtk_box_pack_start (GTK_BOX (hbox2), cancel_button, FALSE, FALSE, 0);
  apply_button=gtk_button_new_with_label("Apply");
  gtk_signal_connect(GTK_OBJECT(apply_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_button, FALSE, FALSE, 0);
  apply_close_button=gtk_button_new_with_label("Apply & Close");
  gtk_signal_connect(GTK_OBJECT(apply_close_button), "clicked",
		     GTK_SIGNAL_FUNC(apply_close_callback),
		     track);
  gtk_box_pack_start (GTK_BOX (hbox2), apply_close_button, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
  gtk_box_pack_end (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 5);

  /* Set values*/
  for(i=0;i<4;i++) text[i] = (gchar *) malloc(sizeof(char[50]));
  for(fptr=track->filterList;fptr!=NULL;fptr=fptr->next){
    if(fptr->ignore) continue;
    get_anchor_filter_text(fptr, text);
    gtk_clist_append(GTK_CLIST(track->filter_clist), text);
  }
  strcpy(text[0],"[Select to add filter]");
  strcpy(text[1],"");
  strcpy(text[2],"");
  strcpy(text[3],"");
  gtk_clist_append(GTK_CLIST(track->filter_clist), text);

  for(i=0;i<4;i++) g_free(text[i]);

  gtk_clist_select_row(GTK_CLIST(track->filter_clist),
                       GTK_CLIST(track->filter_clist)->rows-1,0);

  if(track->row_policy==AUTO_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton1), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==FIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton2), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, FALSE);
  }
  else if(track->row_policy==LIMIT_POLICY){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton3), TRUE);
    gtk_widget_set_sensitive(track->row_spin_button, TRUE);
  }



  gtk_widget_show_all(track->edit_track_window);
}

/*                     DEF: generic_edit_track
 * Callback for the Edit track properties menu option.*/
static void
generic_edit_track(GtkWidget *widget, GtkTrack *track){
  switch(track->entity){
    case CLONES:
      clone_edit_track(track);
      break;
    case MARKERS:
      marker_edit_track(track);
      break;
    case REMARKS:
      remark_edit_track(track);
      break;
    case ANCHORS:
      anchor_edit_track(track);
      break;
    case SEQUENCE:
      sequence_edit_track(track);
      break;
    case NONE:
      break;
  }
}

/*                     DEF: click_in_hotspot
 * Given the coordinate of a mouse click, returns the
 * index of the item that was clicked on, or -1
 * if the click did not occur on an item*/
static int
click_in_hotspot(GtkTrack *t, int x, int y){
  int i;

  for(i=0;i<t->numdata;i++){
    switch(t->entity){
      case CLONES:
	if((showburied==1) && ((t->data.cloneList[i].mattype & EXACT) ||
			       (t->data.cloneList[i].mattype & APPROX) ||
			       (t->data.cloneList[i].mattype & PSEUDO)))
	  continue;
	else if((showburied==2) && (t->data.cloneList[i].mattype & PSEUDO))
	  continue;

	if((x>=t->data.cloneList[i].hotspot.x) &&
	   (x<=t->data.cloneList[i].hotspot.x + t->data.cloneList[i].hotspot.width))
	  if((y>=t->data.cloneList[i].hotspot.y) &&
	     (y<=t->data.cloneList[i].hotspot.y + t->data.cloneList[i].hotspot.height))
	    return i;
	break;
      case MARKERS:
	if((x>=t->data.markerList[i].hotspot.x) &&
	   (x<=t->data.markerList[i].hotspot.x + t->data.markerList[i].hotspot.width))
	  if((y>=t->data.markerList[i].hotspot.y) &&
	     (y<=t->data.markerList[i].hotspot.y + t->data.markerList[i].hotspot.height))
	    return i;
	break;
      case REMARKS:
	if((showburied==1) && ((t->data.remarkList[i].mattype & EXACT) ||
			       (t->data.remarkList[i].mattype & APPROX) ||
			       (t->data.remarkList[i].mattype & PSEUDO)))
	  continue;
	else if((showburied==2) && (t->data.remarkList[i].mattype & PSEUDO))
	  continue;

	if((x>=t->data.remarkList[i].hotspot.x) &&
	   (x<=t->data.remarkList[i].hotspot.x + t->data.remarkList[i].hotspot.width))
	  if((y>=t->data.remarkList[i].hotspot.y) &&
	     (y<=t->data.remarkList[i].hotspot.y + t->data.remarkList[i].hotspot.height))
	    return i;
	break;
      case ANCHORS:
	if((x>=t->data.anchorList[i].hotspot.x) &&
	   (x<=t->data.anchorList[i].hotspot.x + t->data.anchorList[i].hotspot.width))
	  if((y>=t->data.anchorList[i].hotspot.y) &&
	     (y<=t->data.anchorList[i].hotspot.y + t->data.anchorList[i].hotspot.height))
	    return i;
	break;
      case SEQUENCE:
	if((x>=t->data.seqList[i].hotspot.x) &&
	   (x<=t->data.seqList[i].hotspot.x + t->data.seqList[i].hotspot.width)) {
	  if((y>=t->data.seqList[i].hotspot.y) &&
	     (y<=t->data.seqList[i].hotspot.y + t->data.seqList[i].hotspot.height)) {
	     return i;
     }
   }
	if(t->data.seqList[i].ctg_next > 0 &&   x >= t->data.seqList[i].hotspot_next.x  &&
	    x <= t->data.seqList[i].hotspot_next.x + t->data.seqList[i].hotspot_next.width ) {
	  if((y>=t->data.seqList[i].hotspot_next.y) &&
	     (y<=t->data.seqList[i].hotspot_next.y + t->data.seqList[i].hotspot_next.height)) {
	     ctgdisplay(t->data.seqList[i].ctg_next);
        return -1;
     }
   }
	if(t->data.seqList[i].ctg_prev > 0 && x >= t->data.seqList[i].hotspot_prev.x &&
	   x <= t->data.seqList[i].hotspot_prev.x + t->data.seqList[i].hotspot_prev.width) {
	  if((y>=t->data.seqList[i].hotspot_prev.y) &&
	     (y<=t->data.seqList[i].hotspot_prev.y + t->data.seqList[i].hotspot_prev.height)) {
	     ctgdisplay(t->data.seqList[i].ctg_prev);
        return -1;
     }
   }
	break;
      case NONE:
	break;
    }
  }
  return -1;
}

/*                     DEF: gtk_track_xor_line
 * Draws the line that moves with the mouse while
 * resizing a track*/
static void
gtk_track_xor_line (GtkTrack *track)
{
  GtkWidget *widget;
  GdkGCValues values;
  guint16 ypos;

  widget = GTK_WIDGET(track);

  if (!track->xor_gc)
    {
      values.function = GDK_INVERT;
      values.subwindow_mode = GDK_INCLUDE_INFERIORS;
      track->xor_gc = gdk_gc_new_with_values (widget->window,
					      &values,
					      GDK_GC_FUNCTION |
					      GDK_GC_SUBWINDOW);
    }

  ypos = track->line_pos;

  gdk_draw_line (widget->window, track->xor_gc,
		 0,
		 ypos,
		 widget->allocation.width - 1,
		 ypos);
}

/*                     DEF: gtk_track_button_press
 * Handles button presses.  The actual highlighting of items
 * is done in handle_button_press in gtkctgdisplay.c after some
 * preprocessing here, as the
 * highlighting often spans several tracks.  But the opening
 * of popup menus and track resizing is done here.*/
static gint
gtk_track_button_press (GtkWidget *widget, GdkEventButton *event)
{
    gint x,y,y2;
    int index,i;
    GtkTrack *track = GTK_TRACK(widget);

    handled_bpress=FALSE;

    if(!track->in_drag && event->window==track->resize_area->window && event->button==1)
    {
        track->in_drag=TRUE;
        gdk_pointer_grab(track->resize_area->window, FALSE,
                         GDK_POINTER_MOTION_HINT_MASK |
                         GDK_BUTTON1_MOTION_MASK |
                         GDK_BUTTON_RELEASE_MASK,
                         NULL, NULL, event->time);
        gtk_widget_get_pointer(widget->parent,NULL,&y);
        gtk_widget_get_pointer(widget,NULL,&y2);
        y2 = CLAMP(y2,0,track->drawing_area->allocation.height+RESIZE_AREA_HEIGHT/2);
        track->line_pos=y;
        track->view_height=y2;
        gtk_track_xor_line(track);
        handled_bpress=TRUE;
        return TRUE;
    }
    else if (event->window==track->drawing_area->window && event->button==1)
    {
        gtk_widget_get_pointer(track->drawing_area,&x,&y);
        index=click_in_hotspot(track,x,y);
        if (index != -1)
        {
            /* they clicked on a hotspot for this track */
            if (index==track->highdata)
            {
                /* they clicked a hotspot already highlighted */
	            if ((track->entity == CLONES) && clhigh!=NULL)
                {
	                displayclone(track->data.cloneList[track->highdata].index);
                }
	            else if ((track->entity == MARKERS) && (highmark!=-1))
                {
	                displaymarker(track->data.markerList[track->highdata].index);
                }
	            else if ((track->entity == SEQUENCE))
                {
	                displaysequence(track->data.seqList[track->highdata].seq);
                }
	            else if (track->entity == REMARKS && (highremark!=-1))
                {
	                if(track->data.remarkList[track->highdata].type==MARKER_REMARK) /*marker remark*/
	                {
                        displaymarker(track->data.remarkList[track->highdata].index);
                    }
	                else /*clone remark*/
                    {
	                    displayclone(track->data.remarkList[track->highdata].index);
                    }
                }
	            else if(track->entity == ANCHORS)
                {
	                displaymarker(track->data.anchorList[track->highdata].index);
                }

                return TRUE;
            }
            track->highdata=index;
            /* and clear the highdata for all other tracks!! */
            for(i=0 ; i<track_num ; i++)
            {
                if((void*)tracks[i] != (void*)track)
                {
                    ((GtkTrack*)tracks[i])->highdata = -1;
                }
            }
              
            return FALSE;
        }
        else 
        {
            /* they clicked someplace other than a hotspot, so erase highlighting */
            track->highdata=-1;
        }
    }
    /* the next are right-click options */
    else if(event->window==track->drawing_area->window && event->button==3){
    gtk_widget_get_pointer(track->drawing_area,&x,&y);
    if(track->entity==CLONES){
      if((index=click_in_hotspot(track,x,y)) != -1){
        track->focusdata=index;
    gtk_menu_popup(GTK_MENU (track->clone_popup_menu),NULL,NULL,NULL, NULL,
		       event->button, event->time);
        handled_bpress=TRUE;
        return TRUE;
      }
    }
    else if(track->entity==SEQUENCE){
      if((index=click_in_hotspot(track,x,y)) != -1){
        track->focusdata=index;
    gtk_menu_popup(GTK_MENU (track->clone_popup_menu),NULL,NULL,NULL, NULL,
		       event->button, event->time);
        handled_bpress=TRUE;
        return TRUE;
      }
    }
    gtk_menu_popup(GTK_MENU (track->generic_popup_menu),NULL,NULL,NULL, NULL,
                   event->button, event->time);
    handled_bpress=TRUE;
    return TRUE;
    }
    return FALSE;
}

/*                     DEF: gtk_track_button_release
 * Handles button releases.  Used for resizing a track.*/
static gint
gtk_track_button_release (GtkWidget *widget, GdkEventButton *event)
{
  GtkTrack *track;

  g_return_val_if_fail (widget !=NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TRACK(widget), FALSE);

  track=GTK_TRACK(widget);
  if(track->in_drag && (event->button==1)){
    gtk_track_xor_line(track);
    track->in_drag=FALSE;

    gdk_pointer_ungrab(event->time);
    compute_track_size(track);
    if(track->row_policy==FIT_POLICY){
      draw_entities(track);
    }
    track->view_height=0;
    return TRUE;
  }
  return FALSE;
}

/*                     DEF: gtk_track_motion
 * For the dragging when resizing a track*/
static gint
gtk_track_motion (GtkWidget *widget, GdkEventMotion *event)
{
  GtkTrack *track;
  gint y, y2;

  g_return_val_if_fail (widget !=NULL, FALSE);
  g_return_val_if_fail (GTK_IS_TRACK(widget), FALSE);

  gtk_widget_get_pointer(widget->parent,NULL,&y);
  gtk_widget_get_pointer(widget,NULL,&y2);


  track=GTK_TRACK(widget);
  if(track->in_drag){
    if(track->row_policy==FIT_POLICY)
    {  /*Don't place max limit on track height*/
      	if(y2>10) 
		{
			gtk_track_xor_line(track);
			track->line_pos=y;
      		track->view_height=MAX(1,y2);
			gtk_track_xor_line(track);
		}
    }
    else
    {                               /*Limit track height to drawing_area height*/
      if(y2>10 && y2<track->drawing_area->allocation.height+RESIZE_AREA_HEIGHT/2 )
      {
         gtk_track_xor_line(track);
         track->line_pos=y;
         track->view_height=MAX(1,CLAMP(y2,0,track->drawing_area->allocation.height+RESIZE_AREA_HEIGHT/2));
         gtk_track_xor_line(track);
      }
    }
  }
  return TRUE;
}


/* Functions for interfacing with FPCs contigs, root data structures. */

/*                     DEF: compute_track_size
 * Compute the number of rows needed to properly display the
 * entites in the track with the current row policy.  Note that for the auto policy,
 * all the computations in gtk_track_draw_contents, minus the drawing,
 * must be done here.  If a change is made to one function it
 * most likely must be done to the other*/
void
compute_track_size(GtkTrack *t){
  int i,j,maxrows;
  int l_pix, r_pix;
  int marker_placed;
  int remark_placed;
  int clonename_start, clonename_end, clone_start, clone_end, clone_placed;
  int name_width;
  int center;
  int rows[500];
  struct t_clone tc;
  struct t_marker tm;
  struct t_anchor tf;
  struct t_remark tr;
  int view_area, ctg_span;
  int anchorpt;
  char text[CLONE_SZ+2];
  char text2[MARKER_SZ+8];
  char *ptr;
  char anchor_bin[ANCHOR_BIN_SZ+1];
  int left, right, pos;
  int str_w;
  int seq_rows;


  t->contig_pixel_width=(page_end_right - page_end_left + 1) * display_zoom * horiz_scale_factor;

  if(t->row_policy == FIT_POLICY){
    if(t->view_height>0){
      t->numrows = MAX(1, t->view_height/t->rowspacing);
    }
    else{
      if(t->scrolled_window->allocation.height<=1)
        t->numrows = MAX(1, (t->default_height - RESIZE_AREA_HEIGHT)/t->rowspacing);
      else
        t->numrows = MAX(1, t->scrolled_window->allocation.height/t->rowspacing);
    }
	if (t->entity == SEQUENCE) seq_rows = assign_seq_rows(t,t->numrows);

  }
  else if(t->row_policy == LIMIT_POLICY){
    t->numrows=MIN(t->numrows, contigs[currentctg].count);
    if (t->entity == SEQUENCE) seq_rows = assign_seq_rows(t,t->numrows);
  }
  else{  /*row_policy == AUTO_POLICY*/
    if(t->entity==CLONES){
      for(j=0;j<500;j++) rows[j]=INT_MIN;
      /* Go through list to determine the number of rows needed to draw markers,
       * then go through it again to do the drawing*/
      maxrows=0;
      for(i=0; i<t->numdata; i++){
	 tc = t->data.cloneList[i];

         left = tc.left - page_end_left;
         right = tc.right - page_end_left;

	 if((showburied == 1) &&
	    ((tc.mattype & EXACT) || (tc.mattype & APPROX) || (tc.mattype & PSEUDO)))
	   continue;
	 else if((showburied == 2) && (tc.mattype & PSEUDO))
	   continue;

	 if(tc.mattype & PARENT) sprintf(text,"%s*",tc.clone);
	 else if(tc.mattype & PSPARENT) sprintf(text,"%s+",tc.clone);
	 else if(tc.mattype & EXACT) sprintf(text,"%s=",tc.clone);
	 else if(tc.mattype & APPROX) sprintf(text,"%s~",tc.clone);
	 else if(tc.mattype & PSEUDO) sprintf(text,"%s#",tc.clone);
	 else sprintf(text,"%s",tc.clone);

	 l_pix=left*display_zoom*horiz_scale_factor;
	 r_pix=right*display_zoom*horiz_scale_factor;
	 center=display_zoom*horiz_scale_factor*(left + (right - left)/2);
     get_string_dims(text,GTK_WIDGET(t),&name_width,0); 
	 clonename_start=center - (name_width)/2;
	 clonename_end= clonename_start + name_width;


	 clone_start=MIN(l_pix, clonename_start);
	 clone_end=MAX(r_pix, clonename_end);

	 clone_placed=FALSE;
	 for(j=0;j<500 && !clone_placed; j++){
	    if(rows[j]<=clone_start){
	       rows[j]=clone_end;
	       clone_placed=TRUE;
	       if(j>maxrows) maxrows=j;
	    }
	 }
	 if(j==500) g_warning("Clone stack too high for display!");
      }
      t->numrows=maxrows+1;
    }
    if(t->entity==SEQUENCE){
      t->numrows = assign_seq_rows(t,0);   
    }
    else if(t->entity==MARKERS){
      for(j=0;j<500;j++) rows[j]=INT_MIN;
      /* Go through list to determine the number of rows needed to draw clones,
       * then go through it again in gtk_track_draw_contents to do the drawing*/
      maxrows=0;
      for(i=0; i<t->numdata; i++){
	 tm = t->data.markerList[i];

         pos = tm.pos - page_end_left;

     get_string_dims(tm.marker,GTK_WIDGET(t),&str_w,0); 
	 l_pix=pos*display_zoom*horiz_scale_factor - str_w/2;
	 r_pix=l_pix + str_w; 
	 if(r_pix<0) r_pix=0;
	 if(r_pix>t->contig_pixel_width){
	   l_pix -= (r_pix - t->contig_pixel_width + 5);
	 }
	 if(l_pix<0){
	   r_pix += abs(l_pix);
	   l_pix=0;
	 }
	 marker_placed=FALSE;
	 for(j=0;j<500 && !marker_placed; j++){
	    if(rows[j]<=l_pix){
	       rows[j]=r_pix;
	       marker_placed=TRUE;
	       if((j+1)>maxrows) maxrows=j+1;
	    }
	 }
	 if(j==500) g_warning("Marker stack too high for display!");
      }
      t->numrows=maxrows;

    }
    else if(t->entity==ANCHORS){
      for(j=0;j<500;j++) rows[j]=INT_MIN;
      /* Go through list to determine the number of rows needed to draw markers,
       * then go through it again to do the drawing*/
      maxrows=0;
      ctg_span = page_end_right - page_end_left + 1;
      if(GTK_WIDGET(t)->allocation.width <= 1)
	view_area = DEFAULT_TRACK_WIDTH - SCROLLBAR_WIDTH -7;
      else
	view_area = GTK_WIDGET(t)->allocation.width - SCROLLBAR_WIDTH -7;
      for(i=0; i<t->numdata; i++){
	 tf = t->data.anchorList[i];

         pos = tf.pos - page_end_left;

         if(Proj.label_abbrev[0]!='\0'){
	   if ((ptr = strstr(contigs[currentctg].chr_msg,Proj.label_abbrev))!=NULL) {
	     ptr = (char *)&ptr[strlen(Proj.label_abbrev)];
	     g_return_if_fail(sscanf(ptr,"%s", anchor_bin)==1);
	     if(t->show_anchor_bins || !bins_match(anchor_bin, tf.anchor_bin))
	       sprintf(text2,"%s#%s",tf.marker,tf.anchor_bin);
	     else strcpy(text2,tf.marker);
	   }
	   else{
	     sprintf(text2,"%s#%s",tf.marker,tf.anchor_bin);
	   }
         }
         else sprintf(text2,"%s",tf.marker);
         if(t->show_anchor_pos)
           sprintf(text2, "%s(%.1f)", text2, arrp(markerdata,tf.index,MARKER)->anchor_pos);

	 anchorpt = (float)pos * ((float)view_area/(float)ctg_span);
	 l_pix=anchorpt;
     get_string_dims(text2,GTK_WIDGET(t),&str_w,0); 
	 r_pix=anchorpt + str_w; 
	 if(r_pix<0) r_pix=0;
	 if(r_pix>view_area){
	   l_pix -= (r_pix - view_area);
	 }
	 if(l_pix<0){
	   r_pix += abs(l_pix);
	   l_pix=0;
	 }
	 marker_placed=FALSE;
	 for(j=0;j<500 && !marker_placed; j++){
	    if(rows[j]<=l_pix){
	       rows[j]=r_pix;
	       marker_placed=TRUE;
	       if((j+1)>maxrows) maxrows=j+1;
	    }
	 }
	 if(j==500) g_warning("Marker stack too high for display!");
      }
      t->numrows=maxrows;
    }
    else if(t->entity == REMARKS){
      for(j=0;j<500;j++) rows[j]=INT_MIN;
      /* Go through list to determine the number of rows needed to draw markers,
       * then go through it again to do the drawing*/
      maxrows=0;
      for(i=0; i<t->numdata; i++){
	 tr = t->data.remarkList[i];

         pos = tr.pos - page_end_left;

     get_string_dims(tr.message,GTK_WIDGET(t),&str_w,0); 
	 l_pix=pos*display_zoom*horiz_scale_factor - str_w/2; 
	 r_pix=l_pix + str_w; 
	 if(r_pix<0) r_pix=0;
	 if(r_pix>t->contig_pixel_width){
	   l_pix -= (r_pix - t->contig_pixel_width + 5);
	 }
	 if(l_pix<0){
	   r_pix += abs(l_pix);
	   l_pix=0;
	 }
	 remark_placed=FALSE;
	 for(j=0;j<500 && !remark_placed; j++){
	    if(rows[j]<=l_pix){
	       rows[j]=r_pix;
	       remark_placed=TRUE;
	       if((j+1)>maxrows) maxrows=j+1;
	    }
	 }
	 if(j==500) g_warning("Remark stack too high for display!\n");
      }
      t->numrows=maxrows;
    }
  }
  /* Resize drawing area, track according to new parameters.*/
  if((t->view_height>0) && (t->row_policy==FIT_POLICY))
    t->contig_pixel_height=t->view_height-RESIZE_AREA_HEIGHT/2;
  else
    t->contig_pixel_height=t->numrows * t->rowspacing + 20;

  if(t->entity==ANCHORS)
  {
    if (t->scrolled_window->allocation.width > 1)
    {
       t->contig_pixel_width = t->scrolled_window->allocation.width -SCROLLBAR_WIDTH;
    }
    else 
    {
       t->contig_pixel_width = DEFAULT_TRACK_WIDTH -SCROLLBAR_WIDTH;
    }
  }

  /* WMN 9/08 we have to make sure that there is a request with a different size, otherwise
		the track does not get the configure_event to redraw it */
  gtk_widget_set_size_request(GTK_WIDGET(t->drawing_area),1,1);

  gtk_widget_set_size_request(GTK_WIDGET(t->drawing_area),
			t->contig_pixel_width,
			MaX(20,t->contig_pixel_height));

  /* Set track height based on user resize*/
  if(t->view_height>0){
    gtk_widget_set_size_request(GTK_WIDGET(t),
			 -1,
			 MaX(20,t->view_height+RESIZE_AREA_HEIGHT/2 + SCROLLED_WINDOW_BORDER*2));
  }
  /* Limit track height to height of drawable surface*/
  /* WMN 9/3/08 removed this branch as it seemed to prevent the seq track from
	opening up at a reasonable size. Nothing bad seems to happen without it. */
  else if(1) //t->contig_pixel_height<t->scrolled_window->allocation.height)
	{
    gtk_widget_set_size_request(GTK_WIDGET(t),
			 -1,
			 MaX(20,t->contig_pixel_height+RESIZE_AREA_HEIGHT + SCROLLED_WINDOW_BORDER*2));
  }
  else if(t->contig_pixel_height>t->scrolled_window->allocation.height){
    if(t->row_policy==FIT_POLICY)
      gtk_widget_set_size_request(GTK_WIDGET(t),
			   -1,
			   MaX(20,t->contig_pixel_height+RESIZE_AREA_HEIGHT + SCROLLED_WINDOW_BORDER*2));
    else
      gtk_widget_set_size_request(GTK_WIDGET(t),
			   -1,
			   MIN(t->default_height,
			       MaX(20,t->contig_pixel_height+RESIZE_AREA_HEIGHT + SCROLLED_WINDOW_BORDER*2)));
  }
  else if(t->scrolled_window->allocation.height<=1){
    gtk_widget_set_size_request(GTK_WIDGET(t),
			 -1,
			 MaX(20,t->contig_pixel_height+RESIZE_AREA_HEIGHT + SCROLLED_WINDOW_BORDER*2));
  }
}

/*                     DEF: draw_anchor_shade
 * Shade part of anchor track that corresponds to non-viewable portions of other tracks*/
void
draw_anchor_shade(GtkTrack *t){
  int start_view_window, end_view_window;
  int left_view_point, right_view_point;
  int ctg_span, pix_ctg_span;
  int view_area;
  GdkColor color;

  g_return_if_fail(GTK_IS_TRACK(t));
  g_return_if_fail(t->entity == ANCHORS);
  g_return_if_fail(t->shade_pixmap != NULL);

  ctg_span = page_end_right - page_end_left + 1;
  view_area = MIN((page_end_right - page_end_left + 1) * display_zoom * horiz_scale_factor,
		  t->drawing_area->allocation.width);
  start_view_window = GTK_ADJUSTMENT(main_hadj)->value;
  end_view_window = start_view_window + GTK_ADJUSTMENT(main_hadj)->page_size;
  pix_ctg_span = ctg_span * display_zoom * horiz_scale_factor;
  left_view_point = (float)start_view_window * ((float)view_area/(float)pix_ctg_span);
  right_view_point = (float)end_view_window * ((float)view_area/(float)pix_ctg_span);
  if(!t->shade_gc){
    gdk_color_parse("#E6E6FA", &color);

    t->shade_gc=gdk_gc_new(t->drawing_area->window);
    gdk_gc_set_rgb_fg_color(t->shade_gc,&color);
  }
    gdk_color_parse("#E6E6FA", &color);
    gdk_gc_set_rgb_fg_color(t->gc,&color);
    gdk_draw_rectangle(t->pixmap, t->gc,
		     TRUE,0,0,
		     t->drawing_area->allocation.width,
		     t->drawing_area->allocation.height);
    gdk_color_white(t->colormap,&color);
    gdk_gc_set_foreground(t->gc,&color);
    gdk_draw_rectangle(t->pixmap, t->gc,
		     TRUE,left_view_point,0,
		     right_view_point-left_view_point + 1,
		     t->drawing_area->allocation.height);

}


FPC_SEQ_LIST* find_current_seqctg(struct t_seq* pts)
{
    FPC_SEQ_LIST* plctg;
    FPC_SEQ* pseq;
    int nclicks;
    int hit;

    assert(pts);
    pseq = pts->seq;
    assert(pseq);

    if (pts->cycle == 0 || pseq->ctgs == 0) return 0;

    /* make sure there are seqctg hits to cycle through */
    hit = 0;
    for (plctg = pseq->ctgs; plctg; plctg=plctg->next) 
    {
        if (seqctg_hits_ctg(plctg->seq,currentctg)) 
        {
            hit = 1;
            break;   
        }
    }

    if (!hit) return 0;

    for (nclicks = 0, plctg = pseq->ctgs; nclicks < pts->nclicks; nclicks++) 
    {
        while (1)
        {
            if (!plctg) plctg = pseq->ctgs;
            else plctg = plctg->next;            
            if (plctg && seqctg_hits_ctg(plctg->seq,currentctg)) break;           
        }                 
    }

    return plctg;
}


void draw_sequence_contigs(struct t_seq* pts, GtkTrack* t, int y_pix, int l_pix, int r_pix, int sleft, int sright, float corr, GdkColor* curColor)
{
    FPC_SEQ_LIST* pctgs, *highctg;
    int lpx_ctg, rpx_ctg;
    GdkColor color;
    int slen;
    int ctgl, ctgr;
    int scstart, scend, sctmp;

    assert(sleft < sright);
    if (sleft >= sright)
    {
        return;
    }
    slen = sright - sleft;

    assert(pts);
    pctgs = pts->seq->ctgs;
    highctg = find_current_seqctg(pts);
    while (pctgs)
    {
        scstart = pctgs->seq->pos;
        scend = pctgs->seq->pos + pctgs->seq->length;
        if ( intervals_overlap(scstart,scend,sleft,sright))
        {
            if (corr < 0)
            {
                sctmp = sleft + (sright - scend);
                scend = sleft + (sright - scstart);
                scstart = sctmp;
            }

            ctgl = MAX(sleft,scstart) - sleft;
            ctgr = MIN(sright,scend) - sleft;


     
            lpx_ctg = l_pix + (int)( ( ((float)ctgl)* ((float)(r_pix - l_pix))  )/ ((float)slen) );

            rpx_ctg = l_pix + (int)( ( ((float)ctgr)*((float)(r_pix - l_pix))) / ((float)slen) );


            gdk_color_parse("gray", &(color));
            gdk_colormap_alloc_color(t->colormap, &(color), FALSE, TRUE);
            gdk_gc_set_foreground(t->gc,&color);

            gdk_draw_rectangle(t->pixmap, t->gc,TRUE,
                lpx_ctg,y_pix - 2,
		        MaX(rpx_ctg - lpx_ctg,5), 7);
        }
        
        pctgs = pctgs->next;	
    }
   
}

void draw_sequence_hits(struct t_seq* pts, GtkTrack* t, int y_pix, int l_pix, int r_pix, int sleft, int sright, float corr)
{
    SEQHIT* phit;
    CLONE* clp;
    int lpx_ctg, rpx_ctg, px_ctg;
    GdkColor color;
    int slen;
    int sstart, send, stmp;
    FPC_SEQ_LIST* pctgs;
    FPC_SEQ* pctg;

    if (sright <= sleft)
    {
        assert(sright > sleft);
    }
    slen = sright - sleft;
    
    assert(pts);
    phit = pts->seq->hits;

    gdk_color_parse("red", &(color));
    gdk_colormap_alloc_color(t->colormap, &(color), FALSE, TRUE);
    gdk_gc_set_foreground(t->gc,&color);

    while (phit)
    {
        clp = arrp(acedata,phit->clone_idx,CLONE);
        if (clp->ctg == currentctg)
        {
            if (phit->seq_start < sright && phit->seq_end > sleft) 
            {
                sstart = phit->seq_start;
                send = phit->seq_end;
                sstart = MaX(sleft, sstart);
                send = MiN(sright, send);
                if (corr < 0)
                {
                    stmp = sleft + (sright - send);
                    send = sleft + (sright - sstart);
                    sstart = stmp;
                }

                lpx_ctg = l_pix + (int)( ( ((float)(sstart - sleft))* ((float)(r_pix - l_pix))  )/ ((float)slen)  );
                rpx_ctg = l_pix + (int)( ( ((float)(send - sleft))* ((float)(r_pix - l_pix))  )/ ((float)slen)  );

                px_ctg = (int)(.5*(lpx_ctg + rpx_ctg));


                gdk_draw_rectangle(t->pixmap, t->gc,TRUE,
                    lpx_ctg,y_pix - 2,
		            MaX(rpx_ctg - lpx_ctg,5), 7);
            }
        }
        
        phit = phit->next;	
    }
    pctgs = pts->seq->ctgs;
    while (pctgs)
    {
        pctg = pctgs->seq;
        phit = pctg->hits;
        while (phit)
        {
            clp = arrp(acedata,phit->clone_idx,CLONE);
            if (clp->ctg == currentctg)
            {
                sstart = pctg->pos + phit->seq_start;
                send = pctg->pos + phit->seq_end;
                if (sstart   < sright && send > sleft) 
                {
                    sstart = MaX(sleft, sstart);
                    send = MiN(sright, send);
                    if (corr < 0)
                    {
                        stmp = sleft + (sright - send);
                        send = sleft + (sright - sstart);
                        sstart = stmp;
                    }

                    lpx_ctg = l_pix + (int)( ( ((float)(sstart - sleft))* ((float)(r_pix - l_pix))  )/ ((float)slen)  );
                    rpx_ctg = l_pix + (int)( ( ((float)(send - sleft))* ((float)(r_pix - l_pix))  )/ ((float)slen)  );

                    px_ctg = (int)(.5*(lpx_ctg + rpx_ctg));


                    gdk_draw_rectangle(t->pixmap, t->gc,TRUE,
                        lpx_ctg,y_pix - 2,
		                MaX(rpx_ctg - lpx_ctg,5), 7);
                }
            }
            phit = phit->next;
        }        
        pctgs = pctgs->next;
    }    
}
void draw_anchors(GtkTrack* t)
{
   int i,j;
   int l_pix, r_pix, y_pix;
   int row;
   int marker_placed;
   int rows[500];
   struct t_anchor tf;
   char text2[MARKER_SZ+8];
   int view_area, ctg_span;
   int anchorpt;
   char *ptr;
   char anchor_bin[ANCHOR_BIN_SZ+1];
   int pos;
   int str_w;

   ctg_span = page_end_right - page_end_left + 1;
   view_area = MIN((page_end_right - page_end_left + 1) * display_zoom * horiz_scale_factor,
		      t->drawing_area->allocation.width);

    row=t->numrows;
      for(j=0;j<t->numrows;j++) rows[j]=INT_MIN;
      for(i=0; i<t->numdata; i++){
         tf = t->data.anchorList[i];

         pos = tf.pos - page_end_left;

         if(Proj.label_abbrev[0]!='\0'){
	   if ((ptr = strstr(contigs[currentctg].chr_msg,Proj.label_abbrev))!=NULL) {
	     ptr = (char *)&ptr[strlen(Proj.label_abbrev)];
	     g_return_if_fail(sscanf(ptr,"%s", anchor_bin)==1);
	     if(t->show_anchor_bins || !bins_match(anchor_bin, tf.anchor_bin))
	       sprintf(text2,"%s#%s",tf.marker,tf.anchor_bin);
	     else strcpy(text2,tf.marker);
	   }
	   else{
	     sprintf(text2,"%s#%s",tf.marker,tf.anchor_bin);
	   }
         }
         else sprintf(text2,"%s",tf.marker);
         if(t->show_anchor_pos)
           sprintf(text2, "%s(%.1f)", text2, arrp(markerdata,tf.index,MARKER)->anchor_pos);

         anchorpt = (float)pos * ((float)view_area/(float)ctg_span);
        gdk_gc_set_foreground(t->gc,&(t->data.anchorList[i].color));
         l_pix=anchorpt;
         get_string_dims(text2,GTK_WIDGET(t),&str_w,0); 
         r_pix=l_pix + str_w;
         if(r_pix<0) r_pix=0;
         if(r_pix>view_area){
           l_pix -= (r_pix - view_area);
         }
	 if(l_pix<0){
	   r_pix += abs(l_pix);
	   l_pix=0;
	 }
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           y_pix=row*t->rowspacing;
         }
         else{
	   marker_placed=FALSE;
	   for(j=0;j<t->numrows && !marker_placed; j++){
	      if((rows[j]<=l_pix) || (j==t->numrows-1)){
		 rows[j]=r_pix;
		 marker_placed=TRUE;
		 row=j+1;
	      }
	   }
	   y_pix=row * t->rowspacing;
         }
 
         if(t->show_anchor_lines){
	   gdk_draw_line(t->pixmap, t->gc,
			 anchorpt, y_pix-5,
			 anchorpt, t->contig_pixel_height - 3);
         }
         draw_string(GTK_WIDGET(t),t->pixmap,t->gc, text2,l_pix, y_pix-text_height);

         t->data.anchorList[i].hotspot.x = l_pix;
         t->data.anchorList[i].hotspot.y = (y_pix - HOTSPOT_HEIGHT);
         t->data.anchorList[i].hotspot.width = r_pix - l_pix + 1;
         t->data.anchorList[i].hotspot.height = HOTSPOT_HEIGHT;
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           row--;
           if(row<=0) row=t->numrows;
         }
      }
}

void draw_seq_arrow(char dir, int xpix, int ypix, int ctg,GtkWidget* t, GdkPixmap *pm, GdkGC *gc, GdkRectangle* hs, int* pctg)
{
    int arrow_w = 30;
    int arrow_h = 14;
    int gap = 3;
    int i;
    int x,y;
    float m = ((float)arrow_h)/((float)arrow_w*2);
    GdkColor color;
    char numstr[20];

    gdk_color_parse("gray", &color);
    gdk_gc_set_rgb_fg_color(gc,&color);
    for (i = 0; i <= arrow_w; i++)
    {
        x = (dir == 'l' ? xpix - i -gap: xpix + i +gap + 5);
        y = arrow_h/2 - (int)(((float)i)*m);
        gdk_draw_line(pm, gc, x, ypix + y, x, ypix - y);
    }
    gdk_color_parse("black", &color);
    gdk_gc_set_rgb_fg_color(gc,&color);
    for (i = 0; i <= arrow_w; i++)
    {
        x = (dir == 'l' ? xpix - i -gap: xpix + i +gap + 5);
        y = arrow_h/2 - (int)(((float)i)*m);
        gdk_draw_line(pm, gc, x, ypix + y, x, ypix + y);
        gdk_draw_line(pm, gc, x, ypix - y, x, ypix - y);
        if (i == 0)
        {
            gdk_draw_line(pm, gc, x, ypix -arrow_h/2, x, ypix + arrow_h/2);
        }
    }

    *pctg = ctg;
    if (ctg > 0)
    {
         x = (dir == 'l' ? xpix - 40: xpix);
        sprintf(numstr,"ctg %d",ctg);
        ypix = MaX(ypix - 25,2);
        draw_string(t,pm,gc,numstr,x, ypix);

        hs->x = x;
        ypix = MaX(ypix - HOTSPOT_HEIGHT + 3,2);
        hs->y = ypix;
        hs->width = 50;
        hs->height = 3*HOTSPOT_HEIGHT;  
    }
}
void get_prev_next_ctg(struct t_seq* pts, int* prev, int* next)
{
    int sleft, sright;
    struct seqctgpos* ppos;
    int ldiff = 1000000000,rdiff = 1000000000;

    *prev = 0;
    *next = 0;

    sleft = pts->seq_left;
    sright = pts->seq_right;

    /* We need to find the placements with the nearest left/right to these values */

    if (!pts->seq->ctgpos) return;

    for (ppos = pts->seq->ctgpos; ppos; ppos = ppos->next)
    {
        if (ppos->ctg == currentctg) continue;
        if (ppos->seq_end <= sright) // use right not left to allow for overlap
        {
            if (sright - ppos->seq_end < ldiff) 
            {
                *prev = ppos->ctg;
                ldiff = sright - ppos->seq_end;
            }
        }
        else if (ppos->seq_start >= sleft)
        {
            if (ppos->seq_start - sleft <= rdiff)
            {
                *next = ppos->ctg;
                rdiff = ppos->seq_start - sleft;
            }
        }
    }
}
int assign_seq_rows(GtkTrack* t, int limit)
{
	int rowblocks[1000];
	int iseq1, iseq2, row, max_row;
	struct t_seq *ts1, *ts2;
	int counter = 0;

    if (t->numdata >1000)
    {
	    printf("Too many sequences to display\n");
	    return 1;
    }
  
	max_row = 0;
    for (iseq1 = 0; iseq1 < t->numdata; iseq1++)
	{
		ts1 = &(t->data.seqList[iseq1]);
        for (iseq2 = 0; iseq2 < t->numdata; iseq2++)
	    {
        	rowblocks[iseq2] = 0;	
	    }

        for (iseq2 = 0; iseq2 < iseq1; iseq2++)
        { 
            ts2 = &(t->data.seqList[iseq2]);
            if (intervals_overlap(ts1->left-40,ts1->right+40,ts2->left,ts2->right))
            {
             	rowblocks[ts2->row] = 1;
            }
        }

        for (row = 0; row < t->numdata; row++)
        { 
          	if (rowblocks[row] == 0) break;
        }
		if (limit > 0 && row >= limit)
      	{
			row = counter;
			counter++;
			if (counter >= limit) counter = 0;
		}
	   	ts1->row = row;
		if (row > max_row) max_row = row;
	}
	return max_row + 1;
}
void draw_seq_track_entry(GtkTrack* t, int iseq, int high, GdkColor* pcolor)
{
   int l_pix, r_pix, y_pix;
   int row, center;
   int clonename_start, clonename_end, clone_start, clone_end;
   int name_width;
   char text[256];
   GdkColor color;
   int left, right;
   int prev_right=INT_MAX;
   int prev_r_pix=INT_MAX;
   int seq_left_kb, seq_right_kb, seq_len_kb;
   struct t_seq *ts;
   int prev_ctg=0,next_ctg=0;

   ts = &(t->data.seqList[iseq]);
   
   row = ts->row;

   y_pix= 25 + row*t->rowspacing;

    if (high)
    {
       gdk_gc_set_foreground(t->gc,pcolor);
       gdk_draw_rectangle(t->pixmap, t->gc, TRUE,
                        ts->hotspot.x,
                        ts->hotspot.y,
                        ts->hotspot.width,
                        ts->hotspot.height);
    }

     left = ts->left - page_end_left;
     right = ts->right - page_end_left;
    // make room for arrows
    if (left < 40) left = 40;
    if (page_end_right - right < 40) right = page_end_right - 40;

    l_pix=left*display_zoom*horiz_scale_factor;
    r_pix=right*display_zoom*horiz_scale_factor;

    if ((right>prev_right) || (prev_right==INT_MAX)){
       prev_right=right;
       prev_r_pix=r_pix;
    }

    sprintf(text,"%s",ts->seq->name);
    if (ts->corr < 0)
    {
       strcat(text," (REV)");
    }


    center=display_zoom*horiz_scale_factor*(left + (right - left)/2);
    get_string_dims(text,GTK_WIDGET(t),&name_width,0); 
     clonename_start=center - (name_width)/2;
     clonename_end= clonename_start + name_width;


    clone_start=MIN(l_pix, clonename_start);
    clone_end=MAX(r_pix, clonename_end);


    ts->hotspot.x = clone_start;
    ts->hotspot.y = (y_pix - HOTSPOT_HEIGHT + 3);
    ts->hotspot.width = clone_end - clone_start + 1;
    ts->hotspot.height = HOTSPOT_HEIGHT + 3;


    if (ts->seq->ctgs)
    {
       /* Has seqctgs => draw it as a big gap and then fill in */
        gdk_color_parse("black", &color);
        gdk_gc_set_rgb_fg_color(t->gc,&color);
        gdk_draw_rectangle(t->pixmap, t->gc,TRUE,
                 l_pix, y_pix, r_pix-l_pix, 3);

        draw_sequence_contigs(ts,t,y_pix,l_pix,r_pix,ts->seq_left,ts->seq_right,ts->corr,&(ts->color));   
    }
    else
    {            
        gdk_color_parse("gray", &color);
        gdk_gc_set_rgb_fg_color(t->gc,&color);
        gdk_draw_rectangle(t->pixmap, t->gc,TRUE,
                 l_pix, y_pix - 2, r_pix-l_pix, 7);
    }
    draw_sequence_hits(ts, t, y_pix, l_pix, r_pix, ts->seq_left, ts->seq_right,ts->corr);	    

    gdk_color_parse("black", &color);
    gdk_gc_set_rgb_fg_color(t->gc,&color);

    draw_string(GTK_WIDGET(t),t->pixmap,t->gc, text,clonename_start, y_pix-text_height);

    get_prev_next_ctg(ts,&prev_ctg,&next_ctg);

    if (ts->corr > 0)
    {
        if (ts->seq_right < ts->seq->length - Pz.seq_fromendInt*1000)
        {
            draw_seq_arrow('r',r_pix,y_pix,next_ctg,GTK_WIDGET(t),t->pixmap,t->gc,&(ts->hotspot_next),&(ts->ctg_next));
        }
        if (ts->seq_left > Pz.seq_fromendInt*1000 )
        {
            draw_seq_arrow('l',l_pix,y_pix,prev_ctg,GTK_WIDGET(t),t->pixmap,t->gc,&(ts->hotspot_prev),&(ts->ctg_prev));
        }
    }
    else
    {
        if (ts->seq_right < ts->seq->length - Pz.seq_fromendInt*1000)
        {
            draw_seq_arrow('l',l_pix,y_pix,next_ctg,GTK_WIDGET(t),t->pixmap,t->gc,&(ts->hotspot_prev),&(ts->ctg_prev));
        }
        if (ts->seq_left > Pz.seq_fromendInt*1000 )
        {
            draw_seq_arrow('r',r_pix,y_pix,prev_ctg,GTK_WIDGET(t),t->pixmap,t->gc,&(ts->hotspot_next),&(ts->ctg_next));
        }
    }


    seq_left_kb = (int)(ts->seq_left/1000);
    seq_right_kb = (int)(ts->seq_right/1000);
    seq_len_kb = (int)(ts->seq->length/1000);

    /* make sure the start/end numbers aren't jumbled on each other */
    if (r_pix - l_pix < 200)
    {
        r_pix = .5*(r_pix + l_pix) + 110;           
        l_pix = .5*(r_pix + l_pix) - 130;   
        y_pix += 3; // so it's below the arrow        
    }
    sprintf(text,"%d kb",seq_left_kb);
    draw_string(GTK_WIDGET(t),t->pixmap,t->gc, text,(ts->corr >= 0 ? l_pix + 10 : r_pix-50), y_pix+4);

    sprintf(text,"%d kb",seq_right_kb);
    draw_string(GTK_WIDGET(t),t->pixmap,t->gc, text,(ts->corr >= 0 ? r_pix-50 : l_pix + 10), y_pix+4);         

    sprintf(text,"%d kb",seq_len_kb);
    get_string_dims(text,GTK_WIDGET(t),&name_width,0); 
    clonename_start=center - (name_width)/2;
    clonename_end= clonename_start + name_width;

    draw_string(GTK_WIDGET(t),t->pixmap,t->gc, text,clonename_start, y_pix+5);         


    if (ts->seq == highseq) {
       t->highdata = iseq;
    }

    if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
      row--;
      if(row<=0) row=t->numrows;
    }


}

/*                     DEF: gtk_track_draw_contents
 * Draw the entities in data struct to pixmap.  Note that many of the
 * computations done here are mirrored in compute_track_size, so any
 * changes done here most like must be made there too.*/
static void
gtk_track_draw_contents(GtkTrack *t){
   int i,j;
   int l_pix, r_pix, y_pix;
   int row, center;
   int marker_placed;
   int remark_placed;
   int clonename_start, clonename_end, clone_start, clone_end, clone_placed;
   int name_width;
   int* rows;
   struct t_clone tc;
   struct t_marker tm;
   struct t_remark tr;
   char text[CLONE_SZ+2];
   int view_area, ctg_span;
   GdkColor color;
   int left, right, pos;
   int prev_right=INT_MAX;
   int prev_r_pix=INT_MAX;
   int str_w;

   row=t->numrows;
	rows = (int*)malloc((row+1)*sizeof(int));
	if (row >= 500)
	{
		//printf("More than 500 rows in track; only 500 will be displayed\n");fflush(0);
	}
   if(!t->gc)
     t->gc=gdk_gc_new(t->drawing_area->window);
   if(!t->dotln_gc){
     t->dotln_gc=gdk_gc_new(t->drawing_area->window);
     gdk_gc_set_line_attributes(t->dotln_gc,
				0,
				GDK_LINE_ON_OFF_DASH,
				GDK_CAP_BUTT,
				GDK_JOIN_MITER);
     if(gdk_color_parse("gray", &(color))){
       if(!gdk_colormap_alloc_color(t->colormap, &(color), FALSE, TRUE)){
	 printf("WARNING -- could not allocate color\n");
       }
     }
     gdk_gc_set_foreground(t->dotln_gc,&color);
   }
  if (text_height == 0)
  {
      int _w;
     PangoLayout* _pl = gtk_widget_create_pango_layout(GTK_WIDGET(t),"test");
     pango_layout_get_pixel_size(_pl,&_w,&text_height);
     HOTSPOT_HEIGHT = text_height;
     g_object_unref(_pl);
  }

   if(t->entity == CLONES){

      for(j=0;j<t->numrows;j++) rows[j]=INT_MIN;
      for(i=0; i<t->numdata; i++){
         tc = t->data.cloneList[i];

	 left = tc.left - page_end_left;
	 right = tc.right - page_end_left;
         l_pix=left*display_zoom*horiz_scale_factor;
         r_pix=right*display_zoom*horiz_scale_factor;

         if(left>prev_right){
         /* Draw dividing line*/
           pos = prev_r_pix + (l_pix - prev_r_pix)/2;
	       gdk_draw_line(t->pixmap, t->dotln_gc,
			 pos, 0, pos, t->drawing_area->allocation.height);
         }
         if((right>prev_right) || (prev_right==INT_MAX)){
           prev_right=right;
           prev_r_pix=r_pix;
         }

         if((showburied == 1) &&
            ((tc.mattype & EXACT) || (tc.mattype & APPROX) || (tc.mattype & PSEUDO)))
           continue;
         else if((showburied == 2) && (tc.mattype & PSEUDO))
           continue;

         if(tc.mattype & PARENT) sprintf(text,"%s*",tc.clone);
         else if(tc.mattype & PSPARENT) sprintf(text,"%s+",tc.clone);
         else if(tc.mattype & EXACT) sprintf(text,"%s=",tc.clone);
         else if(tc.mattype & APPROX) sprintf(text,"%s~",tc.clone);
         else if(tc.mattype & PSEUDO) sprintf(text,"%s#",tc.clone);
         else sprintf(text,"%s",tc.clone);

         gdk_gc_set_foreground(t->gc,&(t->data.cloneList[i].color));
         center=display_zoom*horiz_scale_factor*(left + (right - left)/2);
         get_string_dims(text,GTK_WIDGET(t),&name_width,0); 
	     clonename_start=center - (name_width)/2;
	     clonename_end= clonename_start + name_width;


         clone_start=MIN(l_pix, clonename_start);
         clone_end=MAX(r_pix, clonename_end);
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           y_pix=row*t->rowspacing;
         }
         else{
	   clone_placed=FALSE;
	   for(j=t->numrows-1;j>=0 && !clone_placed; j--){
	      if((rows[j]<=clone_start) || (j==0)){
		 rows[j]=clone_end;
		 clone_placed=TRUE;
		 row=j;
	      }
	   }
	   y_pix=(row+1) * t->rowspacing;
         }

         gdk_draw_line(t->pixmap, t->gc,
                       l_pix, y_pix, r_pix, y_pix);
         draw_string(GTK_WIDGET(t),t->pixmap,t->gc,text, clonename_start, y_pix-text_height);

         t->data.cloneList[i].hotspot.x = clone_start;
         t->data.cloneList[i].hotspot.y = (y_pix - HOTSPOT_HEIGHT);
         t->data.cloneList[i].hotspot.width = clone_end - clone_start + 1;
         t->data.cloneList[i].hotspot.height = HOTSPOT_HEIGHT;
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           row--;
           if(row<=0) row=t->numrows;
         }
      }
      for(i=0; i<t->numdata; i++){
         tc = t->data.cloneList[i];

         if((showburied == 1) &&
            ((tc.mattype & EXACT) || (tc.mattype & APPROX) || (tc.mattype & PSEUDO)))
           continue;
         else if((showburied == 2) && (tc.mattype & PSEUDO))
           continue;
         copy_to_save_pixmap(t,i);
      }
   }
   else if(t->entity == MARKERS){
      for(j=0;j<t->numrows;j++) rows[j]=INT_MIN;
      for(i=0; i<t->numdata; i++){
         tm = t->data.markerList[i];

         pos = tm.pos - page_end_left;

         gdk_gc_set_foreground(t->gc,&(t->data.markerList[i].color));
         get_string_dims(tm.marker,GTK_WIDGET(t),&str_w,0); 
         l_pix=pos*display_zoom*horiz_scale_factor - str_w/2;
         r_pix=l_pix + str_w; 
         if(r_pix<0) r_pix=0;
         if(r_pix>t->contig_pixel_width){
           l_pix -= (r_pix - t->contig_pixel_width + 5);
         }
         if(l_pix<0){
           r_pix += abs(l_pix);
           l_pix=0;
         }
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           y_pix=row*t->rowspacing;
         }
         else{
	   marker_placed=FALSE;
	   for(j=t->numrows-1;j>=0 && !marker_placed; j--){
	      if((rows[j]<=l_pix) || (j==0)){
		 rows[j]=r_pix;
		 marker_placed=TRUE;
		 row=j+1;
	      }
	   }
	   y_pix=row * t->rowspacing;
         }
         draw_string(GTK_WIDGET(t),t->pixmap,t->gc, tm.marker,l_pix, y_pix-text_height);

         t->data.markerList[i].hotspot.x = l_pix;
         t->data.markerList[i].hotspot.y = (y_pix - HOTSPOT_HEIGHT);
         t->data.markerList[i].hotspot.width = r_pix - l_pix + 1;
         t->data.markerList[i].hotspot.height = HOTSPOT_HEIGHT;
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           row--;
           if(row<=0) row=t->numrows;
         }
      }
      for(i=0; i<t->numdata; i++){
        tm = t->data.markerList[i];
        copy_to_save_pixmap(t,i);
      }
   }
   else if(t->entity == ANCHORS){
      ctg_span = page_end_right - page_end_left + 1;
      view_area = MIN((page_end_right - page_end_left + 1) * display_zoom * horiz_scale_factor,
		      t->drawing_area->allocation.width);
      draw_anchor_shade(t);
     draw_anchors(t);


    }
   else if(t->entity == REMARKS){
      for(j=0;j<t->numrows;j++) rows[j]=INT_MIN;
      for(i=0; i<t->numdata; i++){
         tr = t->data.remarkList[i];

         pos = tr.pos - page_end_left;

         if((showburied == 1) &&
            ((tr.mattype & EXACT) || (tr.mattype & APPROX) || (tr.mattype & PSEUDO)))
           continue;
         else if((showburied == 2) && (tr.mattype & PSEUDO))
           continue;

         gdk_gc_set_foreground(t->gc,&(t->data.remarkList[i].color));
         get_string_dims(tr.message,GTK_WIDGET(t),&str_w,0); 
         l_pix=pos*display_zoom*horiz_scale_factor - str_w/2;
         r_pix=l_pix + str_w; 
         if(r_pix<0) r_pix=0;
         if(r_pix>t->contig_pixel_width){
           l_pix -= (r_pix - t->contig_pixel_width + 5);
         }
	 if(l_pix<0){
	   r_pix += abs(l_pix);
	   l_pix=0;
	 }
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           y_pix=row*t->rowspacing;
         }
         else{
	   remark_placed=FALSE;
	   for(j=t->numrows-1;j>=0 && !remark_placed; j--){
	      if((rows[j]<=l_pix) || (j==0)){
		 rows[j]=r_pix;
		 remark_placed=TRUE;
		 row=j+1;
	      }
	   }
           y_pix=row * t->rowspacing;
         }
         draw_string(GTK_WIDGET(t),t->pixmap,t->gc, tr.message,l_pix, y_pix - text_height);


         t->data.remarkList[i].hotspot.x = l_pix;
         t->data.remarkList[i].hotspot.y = (y_pix - HOTSPOT_HEIGHT);
         t->data.remarkList[i].hotspot.width = r_pix - l_pix + 1;
         t->data.remarkList[i].hotspot.height = HOTSPOT_HEIGHT;
         if((t->row_policy == FIT_POLICY) || (t->row_policy == LIMIT_POLICY)){
           row--;
           if(row<=0) row=t->numrows;
         }
      }
      for(i=0; i<t->numdata; i++){
         tr = t->data.remarkList[i];

         if((showburied == 1) &&
            ((tr.mattype & EXACT) || (tr.mattype & APPROX) || (tr.mattype & PSEUDO)))
           continue;
         else if((showburied == 2) && (tr.mattype & PSEUDO))
           continue;
         copy_to_save_pixmap(t,i);
      }
   }
   else if(t->entity == SEQUENCE){
      row--; // don't draw to the bottom row
      for(j=0;j<t->numrows;j++) rows[j]=INT_MIN;
      for(i=0; i<t->numdata; i++){
         
         draw_seq_track_entry(t,i,0,0);


      }
      for(i=0; i<t->numdata; i++){

         copy_to_save_pixmap(t,i);
      }
   }
	free(rows);
   refresh_track_colors(t);
}

/*                     DEF: compare_clones_name
 * Compare clones by clone name*/
int compare_clones_name(struct t_clone *p1, struct t_clone *p2){
   return strcmp(p1->clone, p2->clone);
}

/*                     DEF: compare_markers_name
 * Compare markers by marker name*/
int compare_markers_name(struct t_marker *p1, struct t_marker *p2){
   return strcmp(p1->marker, p2->marker);
}

/*                     DEF: compare_anchors_name
 * Compare anchors by marker name*/
int compare_anchors_name(struct t_anchor *p1, struct t_anchor *p2){
   return strcmp(p1->marker, p2->marker);
}

/*                     DEF: compare_remarks_name
 * Compare remarks by marker name
 * We also need to compare the index, since we
 * want to show remarks with identical messages but different
 * attachments multiple times.*/
int compare_remarks_name(struct t_remark *p1, struct t_remark *p2){
   int val;
   val = strcmp(p1->message, p2->message);
   if (val != 0) return val;
   if(p1->index < p2->index) return -1;
   if(p1->index > p2->index) return 1;
   return 0;
}

/*                     DEF: compare_clones_left
 * Compare clones by left end value*/
int compare_clones_left(struct t_clone *p1, struct t_clone *p2){
   if(p1->left < p2->left) return -1;
   if(p1->left > p2->left) return 1;
   return 0;
}

/*                     DEF: compare_markers_pos
 * Compare markers by pos value*/
int compare_markers_pos(struct t_marker *p1, struct t_marker *p2){
   if(p1->pos < p2->pos) return -1;
   if(p1->pos > p2->pos) return 1;
   return 0;
}

/*                     DEF: compare_anchors_pos
 * Compare anchors by pos value*/
int compare_anchors_pos(struct t_anchor *p1, struct t_anchor *p2){
   if(p1->pos < p2->pos) return -1;
   if(p1->pos > p2->pos) return 1;
   return 0;
}

/*                     DEF: compare_remarks_pos
 * Compare remarks by pos value*/
int compare_remarks_pos(struct t_remark *p1, struct t_remark *p2){
   if(p1->pos < p2->pos) return -1;
   if(p1->pos > p2->pos) return 1;
   return 0;
}

/*                     DEF: clone_copy
 * Copy contents of clp, color into p*/
static void
clone_copy(struct t_clone *p, GdkColor *color, CLONE *clp, int index){
   strcpy(p->clone,clp->clone);
   p->index=index;
   p->left=clp->x;
   p->right=clp->y;
   p->mattype=clp->mattype;
   p->color.pixel=color->pixel;
   p->color.red=color->red;
   p->color.green=color->green;
   p->color.blue=color->blue;
   p->high = 0;
   p->pixmap=NULL;
}

/*                     DEF: clone_copy_merge
 * Same as clone_copy, but adds to left, right values to put it at
 * end of currentctg*/
static void
clone_copy_merge(struct t_clone *p, GdkColor *color, CLONE *clp, int index){
   strcpy(p->clone,clp->clone);
   p->index=index;
   p->left=clp->x + mergeoffset;
   p->right=clp->y + mergeoffset;
   p->mattype=clp->mattype;
   p->color.pixel=color->pixel;
   p->color.red=color->red;
   p->color.green=color->green;
   p->color.blue=color->blue;
   p->high = 0;
   p->pixmap=NULL;
}

/*                     DEF: marker_copy
 * Copy contents of mkp, color into p*/
static void
marker_copy(struct t_marker *p, GdkColor *color, MARKER *mkp, int pos, int index){
   strcpy(p->marker,mkp->marker);
   p->index=index;
   p->pos=pos;
   p->color.pixel=color->pixel;
   p->color.red=color->red;
   p->color.green=color->green;
   p->color.blue=color->blue;
   p->high = 0;
   p->pixmap=NULL;
}

/*                     DEF: anchor_copy
 * Copy contents of mkp, color into p*/
static void
anchor_copy(struct t_anchor *p, GdkColor *color, MARKER *mkp, int pos, int index){
   strcpy(p->marker,mkp->marker);
   p->index=index;
   p->pos=pos;
   p->color.pixel=color->pixel;
   p->color.red=color->red;
   p->color.green=color->green;
   p->color.blue=color->blue;
   p->high = 0;
   strcpy(p->anchor_bin,mkp->anchor_bin);
}

/*                     DEF: remark_copy
 * Copy contents of rmp, color into p*/
static void
remark_copy(struct t_remark *p, GdkColor *color, struct remark *rmp,
                 int pos, int mattype, int index, int type){
   strcpy(p->message,rmp->message);
   p->pos=pos;
   p->mattype=mattype;
   p->index=index;
   p->type=type;
   p->color.pixel=color->pixel;
   p->color.red=color->red;
   p->color.green=color->green;
   p->color.blue=color->blue;
   p->high = 0;
   p->pixmap=NULL;
}

/*                     DEF: remove_clone
 * Find and remove clone p from pList.
   Not very efficient, so shouldn't be done too much*/
static void
remove_clone(struct t_clone *p, struct t_clone *pList, int *nElem){
   int i,j,k,found=0;

   for(i=0;i<*nElem && !found;i++){
      if(!strcmp(p->clone, pList[i].clone)){
         for(j=i,k=i+1; k<*nElem; j++,k++){  /*Shift everything up*/
	    strcpy(pList[j].clone, pList[k].clone);
	    pList[j].index = pList[k].index;
	    pList[j].left = pList[k].left;
	    pList[j].right = pList[k].right;
	    pList[j].mattype = pList[k].mattype;
	    pList[j].color.pixel = pList[k].color.pixel;
	    pList[j].color.red = pList[k].color.red;
	    pList[j].color.green = pList[k].color.green;
	    pList[j].color.blue = pList[k].color.blue;
	    pList[j].pixmap = pList[k].pixmap;
         }
	 (*nElem)--;
	 found=1;
      }
   }
}

/*                     DEF: remove_marker
 * Find and remove marker p from pList.
   Not very efficient, so shouldn't be done too much*/
static void
remove_marker(struct t_marker *p, struct t_marker *pList, int *nElem){
   int i,j,k,found=0;

   for(i=0;i<*nElem && !found;i++){
      if(!strcmp(p->marker, pList[i].marker)){
         for(j=i,k=i+1; k<*nElem; j++,k++){  /*Shift everything up*/
	    strcpy(pList[j].marker, pList[k].marker);
	    pList[j].index = pList[k].index;
	    pList[j].pos = pList[k].pos;
	    pList[j].color.pixel = pList[k].color.pixel;
	    pList[j].color.red = pList[k].color.red;
	    pList[j].color.green = pList[k].color.green;
	    pList[j].color.blue = pList[k].color.blue;
	    pList[j].pixmap = pList[k].pixmap;
         }
	 (*nElem)--;
	 found=1;
      }
   }
}

/*                     DEF: remove_anchor
 * Find and remove marker p from pList.
   Not very efficient, so shouldn't be done too much*/
static void
remove_anchor(struct t_anchor *p, struct t_anchor *pList, int *nElem){
   int i,j,k,found=0;

   for(i=0;i<*nElem && !found;i++){
      if(!strcmp(p->marker, pList[i].marker)){
         for(j=i,k=i+1; k<*nElem; j++,k++){  /*Shift everything up*/
	    strcpy(pList[j].marker, pList[k].marker);
	    pList[j].index = pList[k].index;
	    pList[j].pos = pList[k].pos;
	    pList[j].color.pixel = pList[k].color.pixel;
	    pList[j].color.red = pList[k].color.red;
	    pList[j].color.green = pList[k].color.green;
	    pList[j].color.blue = pList[k].color.blue;
	    strcpy(pList[j].anchor_bin, pList[k].anchor_bin);
         }
	 (*nElem)--;
	 found=1;
      }
   }
}

/*                     DEF: remove_remark
 * Find and remove remark p from pList.
   Not very efficient, so shouldn't be done too much*/
static void
remove_remark(struct t_remark *p, struct t_remark *pList, int *nElem){
   int i,j,k,found=0;

   for(i=0;i<*nElem && !found;i++){
      if(!strcmp(p->message, pList[i].message)){
         for(j=i,k=i+1; k<*nElem; j++,k++){  /*Shift everything up*/
	    strcpy(pList[j].message, pList[k].message);
	    pList[j].pos = pList[k].pos;
	    pList[j].mattype = pList[k].mattype;
	    pList[j].index = pList[k].index;
	    pList[j].type = pList[k].type;
	    pList[j].color.pixel = pList[k].color.pixel;
	    pList[j].color.red = pList[k].color.red;
	    pList[j].color.green = pList[k].color.green;
	    pList[j].color.blue = pList[k].color.blue;
	    pList[j].pixmap = pList[k].pixmap;
         }
	 (*nElem)--;
	 found=1;
      }
   }
}

/*                     DEF: append_clone
 * Add p to the end of pList*/
static void
append_clone(struct t_clone *p, struct t_clone *pList, int *nElem){
   strcpy(pList[*nElem].clone, p->clone);
   pList[*nElem].index = p->index;
   pList[*nElem].left = p->left;
   pList[*nElem].right = p->right;
   pList[*nElem].mattype = p->mattype;
   pList[*nElem].color.pixel = p->color.pixel;
   pList[*nElem].color.red = p->color.red;
   pList[*nElem].color.green = p->color.green;
   pList[*nElem].color.blue = p->color.blue;
   pList[*nElem].high = p->high;
   pList[*nElem].pixmap = p->pixmap;
   (*nElem)++;
}


static void
append_sequence(struct t_seq *p, struct t_seq *pList, int *nElem){
   memcpy(&pList[*nElem],p,sizeof(struct t_seq));
   (*nElem)++;
}


/*                     DEF: append_marker
 * Add p to the end of pList*/
static void
append_marker(struct t_marker *p, struct t_marker *pList, int *nElem){
   strcpy(pList[*nElem].marker, p->marker);
   pList[*nElem].index = p->index;
   pList[*nElem].pos = p->pos;
   pList[*nElem].color.pixel = p->color.pixel;
   pList[*nElem].color.red = p->color.red;
   pList[*nElem].color.green = p->color.green;
   pList[*nElem].color.blue = p->color.blue;
   pList[*nElem].high = p->high;
   pList[*nElem].pixmap = p->pixmap;
   (*nElem)++;
}

/*                     DEF: append_anchor
 * Add p to the end of pList*/
static void
append_anchor(struct t_anchor *p, struct t_anchor *pList, int *nElem){
   strcpy(pList[*nElem].marker, p->marker);
   pList[*nElem].index = p->index;
   pList[*nElem].pos = p->pos;
   pList[*nElem].color.pixel = p->color.pixel;
   pList[*nElem].color.red = p->color.red;
   pList[*nElem].color.green = p->color.green;
   pList[*nElem].color.blue = p->color.blue;
   pList[*nElem].high = p->high;
   strcpy(pList[*nElem].anchor_bin, p->anchor_bin);
   (*nElem)++;
}

/*                     DEF: append_remark
 * Add p to the end of pList*/
static void
append_remark(struct t_remark *p, struct t_remark *pList, int *nElem){
   strcpy(pList[*nElem].message, p->message);
   pList[*nElem].pos = p->pos;
   pList[*nElem].mattype = p->mattype;
   pList[*nElem].index = p->index;
   pList[*nElem].type = p->type;
   pList[*nElem].color.pixel = p->color.pixel;
   pList[*nElem].color.red = p->color.red;
   pList[*nElem].color.green = p->color.green;
   pList[*nElem].color.blue = p->color.blue;
   pList[*nElem].high = p->high;
   pList[*nElem].pixmap = p->pixmap;
   (*nElem)++;
}

/*                     DEF: compare_strings
 * Returns 1 only if sbjct matches the pattern, which may contain wildcards*/
int
compare_strings(char *sbjct, char *pattern){
  char pat[COMMENT_SZ+1];
  char sub[COMMENT_SZ+1];
  int i,j,patlen,sublen;

  if(!strcmp(pattern,"*") || !strcmp(pattern,"")) return 1;

  strcpy(pat, pattern);
  strcpy(sub, sbjct);
  STRLWR(pat);
  STRLWR(sub);
  patlen = strlen(pat);
  sublen = strlen(sub);

  /* Remove leading and trailing whitespace*/
  for(i=0;(i<patlen) && ((pat[i]==' ') || (pat[i]=='\t')); i++)
    ;
  if(i==patlen) return 1;   /*Empty string*/
  if(i!=0){
    strcpy(pat,(char *)&pat[i]);
    patlen = strlen(pat);
  }
  for(i=patlen-1;(i>=0) && ((pat[i]==' ') || (pat[i]=='\t')); i--)
    ;
  if(i<0) return 1;         /*Empty string*/
  pat[i+1]='\0';
  patlen = strlen(pat);

  if(!strcmp(pat,"*") || !strcmp(pat,"")) return 1;

  if((pat[0]=='*') && (pat[patlen-1]=='*')){  /*Substring match*/
    pat[patlen-1]='\0';
    if(strstr(sub,(char *)&pat[1])!=NULL) return 1;
  }
  else if(pat[0]=='*'){         /*Match ends*/
    for(i=patlen-1, j=sublen-1; (i>=0) && (j>=0) && (pat[i]==sub[j]); i--, j--)
      ;
    if(pat[i]=='*') return 1;   /*We matched up to wildcard*/
  }
  else if(pat[patlen-1]=='*'){  /*Match beginnings*/
    for(i=0, j=0; (i<patlen) && (j<sublen) && (pat[i]==sub[j]); i++, j++)
      ;
    if(pat[i]=='*') return 1;   /*We matched up to wildcard*/
  }
  else{
    if(strstr(sub,pat)!=NULL) return 1;
  }
  return 0;
}

/*                     DEF: bins_match
 *Returns 1 if a and b are the same main anchor bin (only first part checked)*/
static int
bins_match(char *a, char *b){
  int x=0, y=0;
  char p=0, q=0;

  if(sscanf(a, "%d", &x)){
    /*Integer based anchor bin*/
    sscanf(b, "%d", &y);
    if(x==y) return 1;
  }
  else if(sscanf(a, "%c", &p)){
    /*Character based anchor bin*/
    sscanf(b, "%c", &q);
    if(p==q) return 1;
  }
  else g_warning("Could not deduce anchor bin");

  return 0;
}

/*                     DEF: clone_criteria_met
 * Returns 1 if clp meets all filter criteria; 0 otherwise*/
static int
clone_criteria_met(CLONE *clp, struct filters *fptr){
  int met[4];
  int i;
  struct remark *rmp;

  for(i=0;i<4;i++) met[i]=FALSE;

  /* Name criteria*/
  met[0] = compare_strings(clp->clone, fptr->name);

  /* Remark criteria*/
  if(!strcmp(fptr->remark, "*") || !strcmp(fptr->remark, ""))
    met[1]=TRUE;
  else{
    for(rmp=clp->remark; rmp!=NULL; rmp=rmp->next){
      if((met[1]=compare_strings(rmp->message, fptr->remark))) break;
    }
  }

  /* Type criteria*/
  switch(fptr->type){
    case ANY_CLONE:
      met[2]=TRUE;
      break;
    case BAC_CLONE:
      if(clp->class==TYPEBAC) met[2]=TRUE;
      break;
    case CLONE_CLONE:
      if(clp->class==TYPECLONE) met[2]=TRUE;
      break;
    case COSMID_CLONE:
      if(clp->class==TYPECOSMID) met[2]=TRUE;
      break;
    case FOSMID_CLONE:
      if(clp->class==TYPEFOSMID) met[2]=TRUE;
      break;
    case PAC_CLONE:
      if(clp->class==TYPEPAC) met[2]=TRUE;
      break;
    case SEQ_CLONE:
      if(clp->class==TYPESEQ) met[2]=TRUE;
      break;
    case YAC_CLONE:
      if(clp->class==TYPEYAC) met[2]=TRUE;
      break;

    case PARENT_CLONE:
      if(clp->mattype & PARENT) met[2]=TRUE;
      break;
    case PSPARENT_CLONE:
      if(clp->mattype & PSPARENT) met[2]=TRUE;
      break;
    case EXACT_CLONE:
      if(clp->mattype & EXACT) met[2]=TRUE;
      break;
    case APPROX_CLONE:
      if(clp->mattype & APPROX) met[2]=TRUE;
      break;
    case PSEUDO_CLONE:
      if(clp->mattype & PSEUDO) met[2]=TRUE;
      break;
  }

  /* Status criteria*/
  switch(fptr->status){
    case ANY_STATUS:
      met[3]=TRUE;
      break;
    case NONE_STATUS:
      if(clp->seqstat==0) met[3]=TRUE;
      break;
    case TILE_STATUS:
      if(clp->seqstat==TILE) met[3]=TRUE;
      break;
    case SENT_STATUS:
      if(clp->seqstat==SENT) met[3]=TRUE;
      break;
    case READY_STATUS:
      if(clp->seqstat==READY) met[3]=TRUE;
      break;
    case SHOTGUN_STATUS:
      if(clp->seqstat==SHOTGUN) met[3]=TRUE;
      break;
    case FINISHED_STATUS:
      if(clp->seqstat==FINISHED) met[3]=TRUE;
      break;
    case CANCELLED_STATUS:
      if(clp->seqstat==CANCELLED) met[3]=TRUE;
      break;
    case SD_STATUS: /* cari 7apr */
      if(clp->seqstat==SD) met[3]=TRUE;
      break;

  }

  return met[0] && met[1] && met[2] && met[3];
}

/*                     DEF: marker_criteria_met
 * Returns 1 if mkp meets all filter criteria; 0 otherwise*/
static int
marker_criteria_met(MARKER *mkp, struct filters *fptr){
  int met[4];
  int i;
  struct remark *rmp;
  struct markerctgpos *p;
  struct markerclone *cp;
  int ctg, cnt;

  for(i=0;i<4;i++) met[i]=FALSE;

  /* Name criteria*/
  met[0] = compare_strings(mkp->marker, fptr->name);

  /* Remark criteria*/
  if(!strcmp(fptr->remark, "*") || !strcmp(fptr->remark, ""))
    met[1]=TRUE;
  else{
    for(rmp=mkp->remark; rmp!=NULL; rmp=rmp->next){
      if((met[1]=compare_strings(rmp->message, fptr->remark))) break;
    }
  }

  /* Type criteria*/
  switch(fptr->type){
    case ANY_MARK:
      met[2]=TRUE;
      break;
    case BAC_MARK:
      if(mkp->type==markBAC) met[2]=TRUE;
      break;
    case CDNA_MARK:
      if(mkp->type==markCDNA) met[2]=TRUE;
      break;
    case CLONE_MARK:
      if(mkp->type==markCLONE) met[2]=TRUE;
      break;
    case COSMID_MARK:
      if(mkp->type==markCOSMID) met[2]=TRUE;
      break;
    case EBAC_MARK:
      if(mkp->type==markeBAC) met[2]=TRUE;
      break;
    case EMRK_MARK:
      if(mkp->type==markeMRK) met[2]=TRUE;
      break;
    case END_MARK:
      if(mkp->type==markEND) met[2]=TRUE;
      break;
    case FOSMID_MARK:
      if(mkp->type==markFOSMID) met[2]=TRUE;
      break;
    case LOCUS_MARK:
      if(mkp->type==markLOCUS) met[2]=TRUE;
      break;
    case OVERGO_MARK:
      if(mkp->type==markOVERGO) met[2]=TRUE;
      break;
    case PAC_MARK:
      if(mkp->type==markPAC) met[2]=TRUE;
      break;
    case PCR_MARK:
      if(mkp->type==markPCR) met[2]=TRUE;
      break;
    case PROBE_MARK:
      if(mkp->type==markPROBE) met[2]=TRUE;
      break;
    case REPEAT_MARK:
      if(mkp->type==markREP) met[2]=TRUE;
      break;
    case RFLP_MARK:
      if(mkp->type==markRFLP) met[2]=TRUE;
      break;
    case SNP_MARK:
      if(mkp->type==markSNP) met[2]=TRUE;
      break;
    case SSR_MARK:
      if(mkp->type==markSSR) met[2]=TRUE;
      break;
    case STS_MARK:
      if(mkp->type==markSTS) met[2]=TRUE;
      break;
    case TC_MARK:
      if(mkp->type==markTC) met[2]=TRUE;
      break;
    case YAC_MARK:
      if(mkp->type==markYAC) met[2]=TRUE;
      break;
    case FRAME_MARK:
      if((mkp->anchor) && (mkp->frame_type==FRAME)) met[2]=TRUE;
      break;
    case PLACE_MARK:
      if((mkp->anchor) && (mkp->frame_type==PLACE)) met[2]=TRUE;
      break;
  }

  switch(fptr->attachment){
    case ANY_ATTACH:
      met[3]=TRUE;
      break;
    case ONECLONE_ATTACH:
      cnt=0;
      if (arrp(acedata, mkp->cloneindex, CLONE)->ctg == currentctg) cnt++;
      for(cp=mkp->nextclone; cp!=NULL; cp=cp->nextclone)
        if(arrp(acedata, cp->cloneindex, CLONE)->ctg == currentctg) cnt++;
      if(cnt==1) met[3]=TRUE;
      break;
    case MULTCTG_ATTACH:
      ctg=-1;
      cnt=0;
      for(p=mkp->pos; p!=NULL; p=p->next){
        if(p->ctg != ctg) {ctg=p->ctg; cnt++;}
      }
      if(cnt>1) met[3]=TRUE;
      break;
  }

  return met[0] && met[1] && met[2] && met[3];
}

static int
sequence_criteria_met(FPC_SEQ* pseq, struct seqctgpos* ppos, struct filters *fptr){
  int met[4];
  int i;

  assert(pseq);
  assert(ppos);

  for(i=0;i<4;i++) met[i]=FALSE;

  /* Name criteria*/
  met[0] = compare_strings(pseq->name, fptr->name);


  /* Type criteria*/
  switch(fptr->type){
    case ANY_SEQ:
      met[2]=TRUE;
      break;
    case DRAFT_SEQ:
      if(pseq->type==ST_DRAFT) met[2]=TRUE;
      break;
    case CLONE_SEQ:
      if(pseq->type==ST_CLONE) met[2]=TRUE;
      break;
    case REVERSED_SEQ:
      if(ppos->corr < 0) met[2]=TRUE;
      break;

  }


  return met[0] && met[2];
}


/*                     DEF: anchor_criteria_met
 * Returns 1 if mkp meets all filter criteria; 0 otherwise*/
static int
anchor_criteria_met(MARKER *mkp, struct filters *fptr){
  int met[3];
  int i;
  char *ptr;
  char ctg_anchor_bin[ANCHOR_BIN_SZ+1];

  for(i=0;i<3;i++) met[i]=FALSE;

  /* Name criteria*/
  met[0] = compare_strings(mkp->marker, fptr->name);

  /* Type criteria*/
  switch(fptr->type){
    case ANY_ANCHOR:
      met[1]=TRUE;
      break;
    case FRAME_ANCHOR:
      if(mkp->frame_type==FRAME) met[1]=TRUE;
      break;
    case PLACE_ANCHOR:
      if(mkp->frame_type==PLACE) met[1]=TRUE;
      break;
  }

  /* Chromosome criteria*/
  ctg_anchor_bin[0]='\0';
  if ((Proj.label_abbrev[0]!='\0') &&
      ((ptr = strstr(contigs[currentctg].chr_msg,Proj.label_abbrev))!=NULL)){
    ptr = (char *)&ptr[strlen(Proj.label_abbrev)];
    g_return_val_if_fail(sscanf(ptr,"%s", ctg_anchor_bin)==1, FALSE);
  }
  switch(fptr->chrom){
    case ANY_CHROM:
      met[2]=TRUE;
      break;
    case GOOD_CHROM:
      if(bins_match(mkp->anchor_bin, ctg_anchor_bin)) met[2]=TRUE;
      break;
    case BAD_CHROM:
      if(!bins_match(mkp->anchor_bin, ctg_anchor_bin)) met[2]=TRUE;
      break;
  }

  return met[0] && met[1] && met[2];
}

/*                     DEF: remark_criteria_met
 * Returns 1 if rmp meets all filter criteria; 0 otherwise*/
static int
remark_criteria_met(struct remark *rmp, struct filters *fptr, enum remarkTypes type){
  int met[2];
  int i;

  for(i=0;i<2;i++) met[i]=FALSE;

  /* Name criteria*/
  met[0] = compare_strings(rmp->message, fptr->name);

  /* Type criteria*/
  switch(fptr->type){
    case ANY_REMARK:
      met[1]=TRUE;
      break;
    case CLONE_REMARK:
      if(type==CLONE_REMARK) met[1]=TRUE;
      break;
    case CLONE_FPREMARK:
      if(type==CLONE_FPREMARK) met[1]=TRUE;
      break;
    case MARKER_REMARK:
      if(type==MARKER_REMARK) met[1]=TRUE;
      break;
  }

  return met[0] && met[1];
}

/*                     DEF: get_t_remark_mem
 * Since we don't have a count of the number of remarks in
 * a contig, we may need to reallocate memory dynamically.*/
static void
get_t_remark_mem(struct t_remark **p, int numnodes, int *maxnodes){
   /*Allocate memory if we need it.*/
   if (numnodes >= *maxnodes-1) {
      if (*maxnodes==0){
          *maxnodes=100;
          *p = (struct t_remark*) calloc(sizeof(struct t_remark),*maxnodes);
          NOMEM2(*p,"t_remark");
      }
      else {
          *maxnodes+=50;
          *p = (struct t_remark*) realloc(*p, sizeof(struct t_remark)*(*maxnodes));
          NOMEM2(*p,"t_remark");
      }
   }
}

/*                     DEF: gtk_track_clear_data
 * Frees the memory of the 'data' structure in the track*/
void gtk_track_clear_data(GtkTrack *t){
  int i;

  switch(t->entity){
    case MARKERS:
      for(i=0; i<t->numdata; i++){
        if(t->data.markerList[i].pixmap)
          gdk_pixmap_unref(t->data.markerList[i].pixmap);
			t->data.markerList[i].pixmap = 0;
      }
      g_free(t->data.markerList);
      t->data.markerList=NULL;
      break;
    case CLONES:
      for(i=0; i<t->numdata; i++){
        if(t->data.cloneList[i].pixmap)
          gdk_pixmap_unref(t->data.cloneList[i].pixmap);
			t->data.cloneList[i].pixmap = 0;
      }
      g_free(t->data.cloneList);
      t->data.cloneList=NULL;
      break;
    case REMARKS:
      for(i=0; i<t->numdata; i++){
        if(t->data.remarkList[i].pixmap)
          gdk_pixmap_unref(t->data.remarkList[i].pixmap);
			t->data.remarkList[i].pixmap = 0;
      }
      g_free(t->data.remarkList);
      t->data.remarkList=NULL;
      break;
    case ANCHORS:
      g_free(t->data.anchorList);
      t->data.anchorList=NULL;
      break;
    case SEQUENCE:
      for(i=0; i<t->numdata; i++){
        if(t->data.seqList[i].pixmap)
          gdk_pixmap_unref(t->data.seqList[i].pixmap);
			t->data.seqList[i].pixmap = 0;
      }
      g_free(t->data.seqList);
      t->data.seqList=NULL;
      highseq = 0;
      break;
    case NONE:
      break;
  }
}

/*                     DEF: zero_left_end
 * Makes the left end of a ctg zero, as it can go negative.  Shifts clones
 * accordingly*/
void
zero_left_end(int ctg){
  struct contig *cptr;

  if(contigs[ctg].left==0) return;

  if(ctg!=currentctg){
    find_Clone(ctg);   /* get the clones and store data in struct contig */
  }
  /* cari 7apr
    printf("Contig %d left end != 0 (%d) -- Setting to 0.\n", ctg, contigs[ctg].left);
  */
  for(cptr=root;cptr!=NULL;cptr=cptr->new)   /*"new" is next; "next" is clone index*/
    arrp(acedata, cptr->next, CLONE)->selected=TRUE;
  PRTMESS=FALSE;
  move_selected(ctg, ctg, -contigs[ctg].left);
  PRTMESS=TRUE;
  for(cptr=root;cptr!=NULL;cptr=cptr->new)   /*"new" is next; "next" is clone index*/
    arrp(acedata, cptr->next, CLONE)->selected=FALSE;
  if(ctg==currentctg){
    page_end_left = contigs[currentctg].left;
    page_end_right = MIN(Proj.default_page_size-1, contigs[currentctg].right);
  }

  /* Set back to original state*/
  if(ctg!=currentctg && currentctg > 0){ /* WN 7/11/04 must check currentctg
                                        so can be called from outside ctg display*/
    find_Clone(currentctg);   /* get the clones and store data in struct contig */
    orderclones(currentctg);
  }
}


/*                     DEF: gtk_track_fill_data
 * Goes through the root or markerlistroot structures and fills
 * in the track's 'data' structure with the items meeting the
 * filter criteria and are on the current page and are of the
 * entity type displayed in the track.*/
void gtk_track_fill_data(GtkTrack *t){
   struct contig *cptr;
   struct markerlist *mptr;
   CLONE *clp;
   MARKER *mkp;
   struct remark *rmp;
   struct filters *fptr;
   struct t_clone tCln, *tClp;
   struct t_marker tMrk, *tMkp;
   struct t_anchor tFwk, *tFwp;
   struct t_remark tRem, *tRmp;
   struct t_seq tSq;
   int maxdata=0;
   int remark_pos;
   GdkColor defaultColor;
   int count;
   GdkColor merge_color;
   SEQHIT* phit;
   FPC_TREE temptree;
   FPC_TREE* pnode;
   FPC_SEQ* pseq;
   FPC_STACK tempstack;
   int hide;
   struct seqctgpos* ctgpos;

   zero_left_end(currentctg);
   if(merging){
     if(gdk_color_parse("RGB:AB/AB/AB", &merge_color)){
       if(!gdk_colormap_alloc_color(t->colormap, &merge_color, FALSE, TRUE)){
         g_warning("Could not allocate color");
       }
     }
   }

   t->numdata=0;
   if(t->entity==ANCHORS)
      gtk_track_set_hadjustment(GTK_TRACK(t), NULL);
   else
      gtk_track_set_hadjustment(GTK_TRACK(t), GTK_ADJUSTMENT(GTK_TRACK(t)->hadj));
   g_return_if_fail(gdk_color_black(t->colormap, &defaultColor));
   if(t->entity==CLONES){
      if(merging)
        maxdata=contigs[mergecontig1].count + contigs[mergecontig2].count;
      else
        maxdata=contigs[currentctg].count + 10; /* WMN: in case new markers added from marker edit*/
      if((t->data.cloneList=calloc(maxdata,sizeof(struct t_clone)))==NULL)
         g_error("Memory allocation failed");
      count=0;
      /* Must have run find_Clone by this point to have root*/
      for(cptr=root;cptr!=NULL;cptr=cptr->new){   /*"new" is next; "next" is clone index*/
         count++;
         clp=arrp(acedata, cptr->next, CLONE);
         if(merging && (clp->ctg == mergecontig2)){
           if(!CLONE_ON_PAGE(clp->x+mergeoffset, clp->y+mergeoffset)) continue;
         }
         else if(!CLONE_ON_PAGE(clp->x, clp->y)) continue;
	 for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
           if(fptr->ignore) continue;
	   if(clone_criteria_met(clp,fptr)){
             if(count<=contigs[currentctg].count)
	       clone_copy(&tCln, &(fptr->color), clp, cptr->next);
             else
	       clone_copy_merge(&tCln, &(merge_color), clp, cptr->next);
             if(fptr->color_choice==HIDE_COLOR){
	       if((tClp=lfind_fpc(&tCln, t->data.cloneList, &(t->numdata), sizeof(struct t_clone),
		  (void *) compare_clones_name)) != NULL){
                 remove_clone(&tCln, t->data.cloneList, &(t->numdata));
	       }
             }
             else{
	       if((tClp=lfind_fpc(&tCln, t->data.cloneList, &(t->numdata), sizeof(struct t_clone),
		  (void *) compare_clones_name)) != NULL){
                 if(count<=contigs[currentctg].count)
		   clone_copy(tClp, &(fptr->color), clp, cptr->next);  /*Change color*/
	       }
	       else{
		 append_clone(&tCln, t->data.cloneList, &(t->numdata));
	       }
             }
	   }
	 }
      }
      qsort(t->data.cloneList, t->numdata, sizeof(struct t_clone), (void *) compare_clones_left);
   }
   else if(t->entity==SEQUENCE){
      /* Collect each supercontig present in the contig into a temporary tree */
     init_fpc_tree(&temptree);
      for(cptr=root;cptr!=NULL;cptr=cptr->new){   
         clp=arrp(acedata, cptr->next, CLONE); 
         if (clp->ctg == currentctg) { 
            phit = clp->seq_hits;   
            while(phit) {
               pseq = phit->seq;
               assert(pseq);
               if (pseq->parent) {
                  pseq = pseq->parent;
               }
               fpc_tree_insert_node(&temptree,pseq,pseq->name);            
               phit = phit->next;
            }       
         }
      }
      /* Make the track array and figure out where each seq goes */
      maxdata = 1000; //fpc_tree_count_filled_nodes(&temptree);
      t->data.seqList = malloc(maxdata*sizeof(struct t_seq));
      memset(t->data.seqList,0,maxdata*sizeof(struct t_seq));
      fpc_stack_init(&tempstack);  
      pnode = &temptree;
      t->numdata = 0;
      while ((pnode = fpc_tree_next_node(pnode, &tempstack))) 
	  {     
         if (pnode->pdata) 
		 {
            pseq = (FPC_SEQ*)pnode->pdata;
            for (ctgpos = pseq->ctgpos; ctgpos; ctgpos = ctgpos->next) 
			{
               	if (ctgpos->ctg == currentctg) 
				{
                    memset(&tSq,0,sizeof(struct t_seq));
                    tSq.seq = pseq;
                    tSq.ctgpos = ctgpos;
                    tSq.corr = ctgpos->corr;
                    tSq.color = defaultColor;
                    tSq.left = ctgpos->ctg_start;
                    tSq.right = ctgpos->ctg_end;
                    tSq.seq_left = ctgpos->seq_start;
                    tSq.seq_right = ctgpos->seq_end;


                    //compute_seq_location(pseq,ctgpos,page_end_left,page_end_right,&tSq.left,&tSq.right);
                    if (!CLONE_ON_PAGE(tSq.left,tSq.right))  
					{
                     	//printf("%s not on page:%d %d %d %d\n",pseq->name,tSq.left,tSq.right,page_end_left,page_end_right);fflush(0);
                      	continue;
                  	}
                    hide = 0;
                    for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next)
					{
                     	if(fptr->ignore) continue;
                     	if(sequence_criteria_met(pseq,ctgpos,fptr))
						{
                            if(fptr->color_choice != HIDE_COLOR)
                            {
                               tSq.color = fptr->color;
                               hide = 0;
                            }
                            else 
                            {
                               hide = 1;
                            }
                     	}
                    }
                    if (!hide) 
					{
                     	append_sequence(&tSq,t->data.seqList,&(t->numdata));
                    }
               	}  
				if (t->numdata == maxdata) 
				{
					printf("Too many draft sequences to display - stopping at 1000!!\n");fflush(0);
				}            
            }
			if (t->numdata == maxdata) break; 
         }           
      }  
      clear_fpc_tree(&temptree,0);
      fpc_stack_destroy(&tempstack);
   }
   else if(t->entity==MARKERS){
      maxdata=contigs[currentctg].markers;
      if(merging)
        maxdata=contigs[mergecontig1].markers + contigs[mergecontig2].markers;
      else
        maxdata=contigs[currentctg].markers + 10; /* WMN: in case new markers added from marker edit*/
      if((t->data.markerList=calloc(maxdata,sizeof(struct t_marker)))==NULL)
         g_error("Memory allocation failed");
      count=0;
      /* Must have run setmarkerposctg by this point to have markerlistroot*/
      for(mptr=markerlistroot;mptr!=NULL;mptr=mptr->next){
         count++;
         mkp = arrp(markerdata,mptr->markerindex,MARKER);
         if(!MARKER_ON_PAGE(mptr->midpt)) continue;
	 for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
            if(fptr->ignore) continue;
	    if(marker_criteria_met(mkp,fptr)){
              if(count<=contigs[currentctg].markers)
	        marker_copy(&tMrk, &(fptr->color), mkp, mptr->midpt, mptr->markerindex);
              else
	        marker_copy(&tMrk, &merge_color, mkp, mptr->midpt, mptr->markerindex);
              if(fptr->color_choice==HIDE_COLOR){
	        if((tMkp=lfind_fpc(&tMrk, t->data.markerList, &(t->numdata), sizeof(struct t_marker),
	 	   (void *) compare_markers_name)) != NULL){
                  remove_marker(&tMrk, t->data.markerList, &(t->numdata));
	        }
              }
              else{
	        if((tMkp=lfind_fpc(&tMrk, t->data.markerList, &(t->numdata), sizeof(struct t_marker),
	 	   (void *) compare_markers_name)) != NULL){
                  if(count<=contigs[currentctg].markers)
                    marker_copy(tMkp, &(fptr->color), mkp, mptr->midpt, mptr->markerindex);  /*Change color*/
	        }
	        else{
	 	  append_marker(&tMrk, t->data.markerList, &(t->numdata));
	        }
              }
            }
         }
      }
      qsort(t->data.markerList, t->numdata, sizeof(struct t_marker), (void *) compare_markers_pos);
   }
   else if(t->entity==REMARKS){
      /* Search for clone remarks meeting criteria*/
      count=0;
      /* Must have run find_Clone by this point to have root*/
      for(cptr=root;cptr!=NULL;cptr=cptr->new){   /*"new" is next; "next" is clone index*/
         count++;
         clp=arrp(acedata, cptr->next, CLONE);
         if(!CLONE_ON_PAGE(clp->x, clp->y)) continue;
         if(count<=contigs[currentctg].count)
           remark_pos=clp->x + (clp->y - clp->x)/2;
         else
           remark_pos=clp->x + (clp->y - clp->x)/2 + mergeoffset;
         for(rmp=clp->remark;rmp!=NULL;rmp=rmp->next){
	    for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
               if(fptr->ignore) continue;
	       if(remark_criteria_met(rmp,fptr,CLONE_REMARK)){
                  if(t->numdata>=maxdata-1) get_t_remark_mem(&(t->data.remarkList),t->numdata,&maxdata);
                  if(count<=contigs[currentctg].count)
 		    remark_copy(&tRem, &(fptr->color), rmp, remark_pos,
                                clp->mattype, cptr->next, CLONE_REMARK);
                  else
 		    remark_copy(&tRem, &merge_color, rmp, remark_pos,
                                clp->mattype, cptr->next, CLONE_REMARK);
                  if(fptr->color_choice==HIDE_COLOR){
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
		      remove_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
                  else{
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
                      if(count<=contigs[currentctg].count)
		        remark_copy(tRmp, &(fptr->color), rmp, remark_pos,
                                    clp->mattype, cptr->next, CLONE_REMARK);  /*Change color*/
                    }
                    else{
                      append_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
               }
	    }
         }
      }

      /* Search for fp_remarks meeting criteria*/
      count=0;
      /* Must have run find_Clone by this point to have root*/
      for(cptr=root;cptr!=NULL;cptr=cptr->new){   /*"new" is next; "next" is clone index*/
         count++;
         clp=arrp(acedata, cptr->next, CLONE);
         if(!CLONE_ON_PAGE(clp->x, clp->y)) continue;
         if(count<=contigs[currentctg].count){
           remark_pos=clp->x + (clp->y - clp->x)/2;
         }
         else{
           remark_pos=clp->x + (clp->y - clp->x)/2 + mergeoffset;
         }
         for(rmp=clp->fp_remark;rmp!=NULL;rmp=rmp->next){
	    for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
               if(fptr->ignore) continue;
	       if(remark_criteria_met(rmp,fptr,CLONE_FPREMARK)){
                  if(t->numdata>=maxdata-1) get_t_remark_mem(&(t->data.remarkList),t->numdata,&maxdata);
                  if(count<=contigs[currentctg].count)
 		    remark_copy(&tRem, &(fptr->color), rmp, remark_pos,
                                clp->mattype, cptr->next, CLONE_FPREMARK);
                  else
 		    remark_copy(&tRem, &merge_color, rmp, remark_pos,
                                clp->mattype, cptr->next, CLONE_FPREMARK);
                  if(fptr->color_choice==HIDE_COLOR){
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
		      remove_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
                  else{
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
                      if(count<=contigs[currentctg].count)
		        remark_copy(tRmp, &(fptr->color), rmp, remark_pos,
                                    clp->mattype, cptr->next, CLONE_FPREMARK);  /*Change color*/
                    }
                    else{
                      append_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
	       }
	    }
         }
      }

      /* Search for marker remarks meeting criteria*/
      count=0;
      /* Must have run setmarkerposctg by this point to have markerlistroot*/
      for(mptr=markerlistroot;mptr!=NULL;mptr=mptr->next){
         count++;
         mkp = arrp(markerdata,mptr->markerindex,MARKER);
         if(!MARKER_ON_PAGE(mptr->midpt)) continue;
         remark_pos=mptr->midpt;
         remark_pos=mptr->midpt;
         for(rmp=mkp->remark;rmp!=NULL;rmp=rmp->next){
	    for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
               if(fptr->ignore) continue;
	       if(remark_criteria_met(rmp,fptr,MARKER_REMARK)){
                  if(t->numdata>=maxdata-1) get_t_remark_mem(&(t->data.remarkList),t->numdata,&maxdata);
                  if(count<=contigs[currentctg].markers)
 		    remark_copy(&tRem, &(fptr->color), rmp, remark_pos,
                                0, mptr->markerindex, MARKER_REMARK);
                  else
 		    remark_copy(&tRem, &merge_color, rmp, remark_pos,
                                0, mptr->markerindex, MARKER_REMARK);
                  if(fptr->color_choice==HIDE_COLOR){
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
		      remove_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
                  else{
		    if((tRmp=lfind_fpc(&tRem, t->data.remarkList, &(t->numdata), sizeof(struct t_remark),
		       (void *) compare_remarks_name)) != NULL){
                      if(count<=contigs[currentctg].markers)
		        remark_copy(tRmp, &(fptr->color), rmp, remark_pos,
                                    0, mptr->markerindex, MARKER_REMARK);  /*Change color*/
                    }
                    else{
                      append_remark(&tRem, t->data.remarkList, &(t->numdata));
                    }
                  }
	       }
	    }
         }
      }
      qsort(t->data.remarkList, t->numdata, sizeof(struct t_remark), (void *) compare_remarks_pos);
   }
   else if(t->entity==ANCHORS){
      if(merging)
        maxdata=contigs[mergecontig1].markers + contigs[mergecontig2].markers;
      else
        maxdata=contigs[currentctg].markers;  /* Can't have more anchors than markers*/
      if((t->data.anchorList=calloc(maxdata,sizeof(struct t_anchor)))==NULL)
         g_error("Memory allocation failed");
      count=0;
      /* Must have run setmarkerposctg by this point to have markerlistroot*/
      for(mptr=markerlistroot;mptr!=NULL;mptr=mptr->next){
         count++;
         mkp = arrp(markerdata,mptr->markerindex,MARKER);
         if(!MARKER_ON_PAGE(mptr->midpt)) continue;
         if(mkp->anchor && mkp->status!=DELETED){
	    for(fptr=t->filterList;fptr!=NULL;fptr=fptr->next){
               if(fptr->ignore) continue;

	       if(anchor_criteria_met(mkp,fptr)){
                  if(count<=contigs[currentctg].markers)
		    anchor_copy(&tFwk, &(fptr->color), mkp, mptr->midpt, mptr->markerindex);
                  else
		    anchor_copy(&tFwk, &merge_color, mkp, mptr->midpt, mptr->markerindex);
		  if(fptr->color_choice==HIDE_COLOR){
		    if((tFwp=lfind_fpc(&tFwk, t->data.anchorList, &(t->numdata), sizeof(struct t_anchor),
		       (void *) compare_anchors_name)) != NULL){
		      remove_anchor(&tFwk, t->data.anchorList, &(t->numdata));
		    }
		  }
		  else{
		    if((tFwp=lfind_fpc(&tFwk, t->data.anchorList, &(t->numdata), sizeof(struct t_anchor),
		       (void *) compare_anchors_name)) != NULL){
                      if(count<=contigs[currentctg].markers)
		        anchor_copy(tFwp, &(fptr->color), mkp, mptr->midpt, mptr->markerindex);  /*Change color*/
		    }
		    else{
		      append_anchor(&tFwk, t->data.anchorList, &(t->numdata));
		    }
		  }
	       }
	    }
         }
      }
      qsort(t->data.anchorList, t->numdata, sizeof(struct t_anchor), (void *) compare_anchors_pos);
   }
}

void* lfind_fpc(const void* key, const void* base, int* nmemb, int size, int(*compar)(const void*, const void*))
{
	size_t szt1, szt2;
	szt2 = (size_t)size;
	szt1 = (size_t)*nmemb;
	return lfind(key,base,&szt1,szt2,compar);
}
void* lsearch_fpc(const void* key, const void* base, int* nmemb, int size, int(*compar)(const void*, const void*))
{
	size_t szt1, szt2;
	void* out;

	szt2 = (size_t)size;
	szt1 = (size_t)*nmemb;
	out = lsearch(key,base,&szt1,szt2,compar);
	*nmemb = (int)szt1;
	return out;
}

/***********************************************************************************************

Functions for the sequence detail view print/save

**************************************************************************************************/

#define GETCURDIR (strcmp(dirName,"") ? dirName : ".")

static
void do_print(){
  GdkPixbuf *pb;
  char file_name[83];
  char file_path[MAXPATHLEN+1];
  char cmd_str[MAXPATHLEN+MAX_PRINT_COMMAND_LEN+2];
  GError *err = 0;

  sprintf(file_name, "seq_detail_view.ps");
  sprintf(file_path, "%s/%s", GETCURDIR, file_name);
  
  printf("Preparing to print... ");
  fflush(stdout);
  pb = gdk_pixbuf_get_from_drawable(0,detail_pm, NULL, 0, 0, 0,0,-1, -1);
  gdk_pixbuf_savev(pb, file_path, "jpeg",0,0,&err);
if (err != NULL)
{
    printf("error %s\n",err->message);fflush(0);
}
  sprintf(cmd_str, "%s %s\n", print_command, file_path);
  printf("printing... ");
  fflush(stdout);
  system(cmd_str);
  sprintf(cmd_str, "rm -f %s\n", file_path);
  system(cmd_str);
  printf("done.\n");
  g_object_unref(pb);
}
  
/*                     DEF: do_save
 * Creates an image by calling get_ctg_image, and saves it
 * in the selected format*/
static
void do_save(){
  GdkPixbuf *pb;
  char file_name[84];
  char file_path[MAXPATHLEN+1];
  char type[30];
  GError* err = 0;

  switch(save_type){
    case JPEG:
      sprintf(file_name,"%s.jpg",save_file);
      sprintf(type,"jpeg");
      break;
    case GIF:
      sprintf(file_name,"%s.gif",save_file);
      sprintf(type,"gif");
      break;
    case TIFF:
      sprintf(file_name,"%s.tif",save_file);
      sprintf(type,"tiff");
      break;
    case PNG:
      sprintf(file_name,"%s.png",save_file);
      sprintf(type,"png");
      break;
    case BITMAP:
      sprintf(file_name,"%s.bmp",save_file);
      sprintf(type,"bmp");
      break;
  }
  sprintf(file_path, "%s/%s", GETCURDIR, file_name);
  printf("Saving file to %s... ",file_path);
  fflush(stdout);
  pb = gdk_pixbuf_get_from_drawable(0,detail_pm, NULL, 0, 0, 0,0,-1, -1);
  gdk_pixbuf_savev(pb, file_path, type,0,0,&err);
  printf("done.\n");
  g_object_unref(pb);
}

/*                     DEF: entry1_callback
 * Print command entry callback.*/
static void
entry1_callback(GtkWidget *widget, gpointer data){
  strcpy(print_command, gtk_entry_get_text(GTK_ENTRY(widget)));
}
/*                     DEF: entry2_callback
 * Save command entry callback.*/
static void
entry2_callback(GtkWidget *widget, gpointer data){
  strcpy(save_file, gtk_entry_get_text(GTK_ENTRY(widget)));
}

/*                     DEF: print_radiobutton_callback
 * Print/save toggle*/
static void
print_radiobutton_callback(GtkWidget *widget, gpointer data){
  if (GTK_TOGGLE_BUTTON (widget)->active){
    action=0;
    gtk_label_set_text(GTK_LABEL(action_button_label), "Print");
    gtk_widget_set_sensitive(entry1, TRUE);
    gtk_widget_set_sensitive(entry2, FALSE);
    gtk_widget_set_sensitive(save_optionmenu, FALSE);
  }
}

/*                     DEF: save_radiobutton_callback
 * Print/save toggle*/
static void
save_radiobutton_callback(GtkWidget *widget, gpointer data){
  if (GTK_TOGGLE_BUTTON (widget)->active){
    action=1;
    gtk_label_set_text(GTK_LABEL(action_button_label), "Save");
    gtk_widget_set_sensitive(entry1, FALSE);
    gtk_widget_set_sensitive(entry2, TRUE);
    gtk_widget_set_sensitive(save_optionmenu, TRUE);
  }
}


/*                     DEF: save_menu_callback1
 * Save file format = JPEG*/
static void
save_menu_callback1(GtkWidget *widget, gpointer data){
  save_type = JPEG;
}

/*                     DEF: save_menu_callback2
 * Save file format = GIF*/
static void
save_menu_callback2(GtkWidget *widget, gpointer data){
  save_type = GIF;
}

/*                     DEF: save_menu_callback3
 * Save file format = TIFF*/
static void
save_menu_callback3(GtkWidget *widget, gpointer data){
  save_type = TIFF;
}

/*                     DEF: save_menu_callback4
 * Save file format = PNG*/
static void
save_menu_callback4(GtkWidget *widget, gpointer data){
  save_type = PNG;
}

/*                     DEF: save_menu_callback5
 * Save file format = BITMAP*/
static void
save_menu_callback5(GtkWidget *widget, gpointer data){
  save_type = BITMAP;
}


/*                     DEF: cancel_button_callback
 * Cancel button callback (duh)*/
static void
cancel_button_callback(GtkWidget *widget, gpointer data){
  if(print_window!=NULL)
    gtk_widget_destroy(print_window);
  print_window=NULL;
}

/*                     DEF: action_button_callback
 * Perform either a print or a save.*/
static void
action_button_callback(GtkWidget *widget, gpointer data){
  if(action==0)
    do_print();
  else
    do_save();
  gtk_widget_destroy(print_window);
}

/*                     DEF: print_dialog
 * Graphics stuff for the print/save window*/
void
detail_print_dialog(){
  GtkWidget *vbox, *vbox2;
  GtkWidget *hbox, *hbox2;
  GtkWidget *label;
  GtkWidget *frame;
  GtkWidget *print_radiobutton;
  GtkWidget *save_radiobutton;
  GtkWidget *save_menu;
  GtkWidget *jpeg1;
  GtkWidget *gif1;
  GtkWidget *tiff1;
  GtkWidget *png1;
  GtkWidget *bitmap1;
  GtkWidget *cancel_button;
  char title[20];
  char action_button_text[7];
 
  if(print_window!=NULL){
    gdk_window_raise(print_window->window);
    return;
  }

  sprintf(save_file, "ctg%d", currentctg);
  sprintf(title, "Print/Save Ctg%d", currentctg);
  if(action==0) strcpy(action_button_text, "Print");
  else strcpy(action_button_text, "Save");

  print_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (print_window), 5);
  gtk_window_set_title (GTK_WINDOW (print_window), title);
  gtk_window_set_policy (GTK_WINDOW (print_window), FALSE, TRUE, FALSE);
  gtk_signal_connect (GTK_OBJECT (print_window), "destroy",
		      GTK_SIGNAL_FUNC (cancel_button_callback), NULL);

  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add (GTK_CONTAINER (print_window), vbox);

  hbox=gtk_hbox_new(FALSE,5);
  frame = gtk_frame_new("Print");
  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
  vbox2=gtk_vbox_new(FALSE,7);
  gtk_container_set_border_width (GTK_CONTAINER (vbox2), 2);

  print_radiobutton = gtk_radio_button_new_with_label(NULL, "Send to printer");
  gtk_signal_connect (GTK_OBJECT (print_radiobutton), "clicked",
		      GTK_SIGNAL_FUNC (print_radiobutton_callback), NULL);
  gtk_box_pack_start (GTK_BOX (vbox2), print_radiobutton, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  label = gtk_label_new("Print command:");
  gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
  entry1 = gtk_entry_new_with_max_length(MAX_PRINT_COMMAND_LEN);
  gtk_entry_set_text(GTK_ENTRY(entry1), print_command);
  gtk_signal_connect (GTK_OBJECT (entry1), "changed",
		      GTK_SIGNAL_FUNC (entry1_callback), NULL);
  gtk_box_pack_start(GTK_BOX(hbox2), entry1, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);

  gtk_container_add(GTK_CONTAINER(frame), vbox2);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);


  hbox=gtk_hbox_new(FALSE, 5);
  frame = gtk_frame_new("Save");
  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
  vbox2=gtk_vbox_new(FALSE,7);
  gtk_container_set_border_width (GTK_CONTAINER (vbox2), 2);

  save_radiobutton = gtk_radio_button_new_with_label(
                       gtk_radio_button_group(GTK_RADIO_BUTTON(print_radiobutton)),
                       "Save to file");
  gtk_signal_connect (GTK_OBJECT (save_radiobutton), "clicked",
		      GTK_SIGNAL_FUNC (save_radiobutton_callback), NULL);
  gtk_box_pack_start (GTK_BOX (vbox2), save_radiobutton, FALSE, FALSE, 0);

  hbox2=gtk_hbox_new(FALSE, 5);
  label = gtk_label_new("File name:");
  gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
  entry2 = gtk_entry_new_with_max_length(MAX_PRINT_COMMAND_LEN);
  gtk_entry_set_text(GTK_ENTRY(entry2), save_file);
  gtk_signal_connect (GTK_OBJECT (entry2), "changed",
		      GTK_SIGNAL_FUNC (entry2_callback), NULL);
  gtk_box_pack_start(GTK_BOX(hbox2), entry2, TRUE, TRUE, 0);

  save_optionmenu=gtk_option_menu_new();
  gtk_box_pack_start(GTK_BOX(hbox2), save_optionmenu, FALSE, FALSE, 0);
  save_menu=gtk_menu_new();

  jpeg1 = gtk_menu_item_new_with_label ("Jpeg (.jpg)");
  gtk_signal_connect (GTK_OBJECT (jpeg1), "activate",
		      GTK_SIGNAL_FUNC (save_menu_callback1),
		      NULL);
  gtk_widget_show(jpeg1);
  gtk_container_add (GTK_CONTAINER (save_menu), jpeg1);

  gif1 = gtk_menu_item_new_with_label ("Gif (.gif)");
  gtk_signal_connect (GTK_OBJECT (gif1), "activate",
		      GTK_SIGNAL_FUNC (save_menu_callback2),
		      NULL);
  gtk_widget_show(gif1);
  gtk_container_add (GTK_CONTAINER (save_menu), gif1);

  tiff1 = gtk_menu_item_new_with_label ("Tiff (.tif)");
  gtk_signal_connect (GTK_OBJECT (tiff1), "activate",
		      GTK_SIGNAL_FUNC (save_menu_callback3),
		      NULL);
  gtk_widget_show(tiff1);
  gtk_container_add (GTK_CONTAINER (save_menu), tiff1);

  png1 = gtk_menu_item_new_with_label ("PNG (.png)");
  gtk_signal_connect (GTK_OBJECT (png1), "activate",
		      GTK_SIGNAL_FUNC (save_menu_callback4),
		      NULL);
  gtk_widget_show(png1);
  gtk_container_add (GTK_CONTAINER (save_menu), png1);

  bitmap1 = gtk_menu_item_new_with_label ("Bitmap (.bmp)");
  gtk_signal_connect (GTK_OBJECT (bitmap1), "activate",
		      GTK_SIGNAL_FUNC (save_menu_callback5),
		      NULL);
  gtk_widget_show(bitmap1);
  gtk_container_add (GTK_CONTAINER (save_menu), bitmap1);

  gtk_option_menu_set_menu (GTK_OPTION_MENU (save_optionmenu), save_menu);  
  gtk_option_menu_set_history (GTK_OPTION_MENU (save_optionmenu), save_type);  
  gtk_widget_show(save_optionmenu);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);

  gtk_container_add(GTK_CONTAINER(frame), vbox2);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);



  cancel_button = gtk_button_new_with_label("Cancel");
  gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
		      GTK_SIGNAL_FUNC (cancel_button_callback),
		      NULL);
  gtk_box_pack_start (GTK_BOX (hbox), cancel_button, TRUE, TRUE, 0);

  action_button = gtk_button_new();
  action_button_label = gtk_label_new(action_button_text);
  gtk_misc_set_alignment (GTK_MISC (action_button_label), 0.5, 0.5);
  gtk_container_add (GTK_CONTAINER (action_button), action_button_label);
  gtk_signal_connect (GTK_OBJECT (action_button), "clicked",
		      GTK_SIGNAL_FUNC (action_button_callback),
		      NULL);
  gtk_box_pack_start (GTK_BOX (hbox), action_button, TRUE, TRUE, 0);


  /* Set defaults*/
  if(action==0){
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_radiobutton), TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_radiobutton), FALSE);
    gtk_widget_set_sensitive(entry1, TRUE);
    gtk_widget_set_sensitive(entry2, FALSE);
    gtk_widget_set_sensitive(save_optionmenu, FALSE);
  }
  else{
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_radiobutton), FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_radiobutton), TRUE);
    gtk_widget_set_sensitive(entry1, FALSE);
    gtk_widget_set_sensitive(entry2, TRUE);
    gtk_widget_set_sensitive(save_optionmenu, TRUE);
  }



  gtk_widget_show_all(print_window);
}

